summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2021-02-09 16:00:23 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2021-02-09 16:00:23 +0900
commit5ce840383da7cf82ffa7dfaeda187f3fe3d591a7 (patch)
treef93fb33cde2a62aa414b61dca085f3fd0613aaca
parentd9f0d99e31569835e295b990029c6dd19554299c (diff)
downloadgpg2-5ce840383da7cf82ffa7dfaeda187f3fe3d591a7.tar.gz
gpg2-5ce840383da7cf82ffa7dfaeda187f3fe3d591a7.tar.bz2
gpg2-5ce840383da7cf82ffa7dfaeda187f3fe3d591a7.zip
Imported Upstream version 2.1.22upstream/2.1.22
-rw-r--r--AUTHORS27
-rw-r--r--COPYING.GPL2339
-rw-r--r--COPYING.LGPL21509
-rw-r--r--COPYING.LGPL3 (renamed from COPYING.LIB)0
-rw-r--r--Makefile.am3
-rw-r--r--NEWS51
-rw-r--r--README2
-rw-r--r--agent/agent.h26
-rw-r--r--agent/call-pinentry.c14
-rw-r--r--agent/command-ssh.c51
-rw-r--r--agent/command.c33
-rw-r--r--agent/divert-scd.c8
-rw-r--r--agent/findkey.c135
-rw-r--r--agent/genkey.c4
-rw-r--r--agent/gpg-agent.c153
-rw-r--r--agent/pksign.c155
-rw-r--r--agent/preset-passphrase.c3
-rw-r--r--agent/protect.c59
-rw-r--r--artwork/banner/Bungee-Regular.ttfbin0 -> 126736 bytes
-rw-r--r--artwork/banner/Bungee-license.txt92
-rw-r--r--artwork/banner/Raleway-ExtraBold.ttfbin0 -> 178128 bytes
-rw-r--r--artwork/banner/Raleway-SemiBold.ttfbin0 -> 180492 bytes
-rw-r--r--artwork/banner/Raleway-license.txt94
-rw-r--r--artwork/banner/banner-full.pngbin0 -> 49267 bytes
-rw-r--r--artwork/banner/banner-half.pngbin0 -> 82305 bytes
-rw-r--r--artwork/banner/banner-rectangle.pngbin0 -> 82061 bytes
-rw-r--r--artwork/banner/banner-skyscraper.pngbin0 -> 52697 bytes
-rw-r--r--artwork/banner/banner.svg509
-rw-r--r--build-aux/Vagrantfile36
-rw-r--r--build-aux/speedo.mk4
-rw-r--r--build-aux/speedo/w32/g4wihelp.c5
-rw-r--r--common/Makefile.am3
-rw-r--r--common/argparse.c45
-rw-r--r--common/argparse.h14
-rw-r--r--common/compliance.c590
-rw-r--r--common/compliance.h88
-rw-r--r--common/homedir.c91
-rw-r--r--common/logging.c3
-rw-r--r--common/miscellaneous.c10
-rw-r--r--common/ssh-utils.c128
-rw-r--r--common/ssh-utils.h6
-rw-r--r--common/status.h4
-rw-r--r--common/stringhelp.c36
-rw-r--r--common/stringhelp.h4
-rw-r--r--common/sysutils.c46
-rw-r--r--common/sysutils.h4
-rw-r--r--common/t-ssh-utils.c103
-rw-r--r--common/t-stringhelp.c76
-rw-r--r--common/util.h2
-rw-r--r--configure.ac7
-rw-r--r--dirmngr/Makefile.am8
-rw-r--r--dirmngr/dirmngr-client.c2
-rw-r--r--dirmngr/dirmngr.c88
-rw-r--r--dirmngr/dirmngr.h9
-rw-r--r--dirmngr/dirmngr_ldap.c2
-rw-r--r--dirmngr/dns-stuff.c49
-rw-r--r--dirmngr/dns.c288
-rw-r--r--dirmngr/http.c328
-rw-r--r--dirmngr/http.h5
-rw-r--r--dirmngr/ks-action.c16
-rw-r--r--dirmngr/ks-engine-finger.c2
-rw-r--r--dirmngr/ks-engine-hkp.c272
-rw-r--r--dirmngr/ks-engine-http.c26
-rw-r--r--dirmngr/ldap.c1
-rw-r--r--dirmngr/loadswdb.c1
-rw-r--r--dirmngr/server.c42
-rw-r--r--dirmngr/t-http.c31
-rw-r--r--doc/DETAILS33
-rw-r--r--doc/Makefile.am10
-rw-r--r--doc/dirmngr.texi25
-rw-r--r--doc/examples/vsnfd.prf2
-rw-r--r--doc/faq.org31
-rw-r--r--doc/gnupg.texi4
-rw-r--r--doc/gpg-agent.texi7
-rw-r--r--doc/gpg.texi417
-rw-r--r--doc/gpgsm.texi7
-rw-r--r--doc/tools.texi2
-rw-r--r--doc/wks.texi340
-rw-r--r--doc/yat2m.c14
-rw-r--r--g10/Makefile.am7
-rw-r--r--g10/build-packet.c10
-rw-r--r--g10/call-agent.c49
-rw-r--r--g10/call-agent.h6
-rw-r--r--g10/call-dirmngr.c30
-rw-r--r--g10/call-dirmngr.h2
-rw-r--r--g10/card-util.c51
-rw-r--r--g10/cpr.c2
-rw-r--r--g10/decrypt-data.c12
-rw-r--r--g10/encrypt.c69
-rw-r--r--g10/export.c3
-rw-r--r--g10/free-packet.c6
-rw-r--r--g10/getkey.c510
-rw-r--r--g10/gpg.c134
-rw-r--r--g10/gpgcompose.c75
-rw-r--r--g10/gpgv.c1
-rw-r--r--g10/import.c405
-rw-r--r--g10/key-check.c655
-rw-r--r--g10/key-check.h28
-rw-r--r--g10/keydb.h34
-rw-r--r--g10/keyedit.c803
-rw-r--r--g10/keyedit.h60
-rw-r--r--g10/keygen.c7
-rw-r--r--g10/keyid.c40
-rw-r--r--g10/keylist.c62
-rw-r--r--g10/keyserver-internal.h2
-rw-r--r--g10/keyserver.c55
-rw-r--r--g10/main.h32
-rw-r--r--g10/mainproc.c73
-rw-r--r--g10/misc.c106
-rw-r--r--g10/options.h13
-rw-r--r--g10/packet.h10
-rw-r--r--g10/parse-packet.c8
-rw-r--r--g10/pkclist.c8
-rw-r--r--g10/pubkey-enc.c25
-rw-r--r--g10/sig-check.c21
-rw-r--r--g10/sign.c34
-rw-r--r--g10/skclist.c16
-rw-r--r--g10/sqrtu32.c244
-rw-r--r--g10/sqrtu32.h14
-rw-r--r--g10/tofu.c18
-rw-r--r--kbx/kbxutil.c2
-rw-r--r--po/ca.po202
-rw-r--r--po/cs.po253
-rw-r--r--po/da.po245
-rw-r--r--po/de.po266
-rw-r--r--po/el.po204
-rw-r--r--po/eo.po197
-rw-r--r--po/es.po248
-rw-r--r--po/et.po202
-rw-r--r--po/fi.po205
-rw-r--r--po/fr.po250
-rw-r--r--po/gl.po202
-rw-r--r--po/hu.po204
-rw-r--r--po/id.po205
-rw-r--r--po/it.po202
-rw-r--r--po/ja.po224
-rw-r--r--po/nb.po240
-rw-r--r--po/pl.po252
-rw-r--r--po/pt.po201
-rw-r--r--po/ro.po229
-rw-r--r--po/ru.po242
-rw-r--r--po/sk.po204
-rw-r--r--po/sv.po244
-rw-r--r--po/tr.po244
-rw-r--r--po/uk.po247
-rw-r--r--po/zh_CN.po228
-rw-r--r--po/zh_TW.po237
-rw-r--r--scd/app-openpgp.c94
-rw-r--r--scd/ccid-driver.c30
-rw-r--r--scd/scdaemon.c9
-rw-r--r--sm/call-agent.c19
-rw-r--r--sm/decrypt.c53
-rw-r--r--sm/encrypt.c54
-rw-r--r--sm/gpgsm.c56
-rw-r--r--sm/gpgsm.h2
-rw-r--r--sm/keylist.c5
-rw-r--r--sm/sign.c40
-rw-r--r--sm/verify.c42
-rw-r--r--tests/fake-pinentries/README.txt2
-rw-r--r--tests/gpgme/gpgme-defs.scm4
-rw-r--r--tests/gpgscm/ffi.c2
-rw-r--r--tests/gpgscm/ffi.scm3
-rw-r--r--tests/gpgscm/init.scm6
-rw-r--r--tests/gpgscm/main.c19
-rw-r--r--tests/gpgscm/repl.scm12
-rw-r--r--tests/gpgscm/scheme.c53
-rw-r--r--tests/gpgscm/tests.scm128
-rw-r--r--tests/gpgsm/gpgsm-defs.scm4
-rw-r--r--tests/openpgp/Makefile.am3
-rw-r--r--tests/openpgp/all-tests.scm22
-rw-r--r--tests/openpgp/defs.scm10
-rwxr-xr-xtests/openpgp/gpgv.scm75
-rw-r--r--tests/openpgp/shell.scm28
-rw-r--r--tests/openpgp/signed-messages.scm281
-rwxr-xr-xtests/openpgp/ssh-export.scm4
-rwxr-xr-xtests/openpgp/verify.scm268
-rw-r--r--tools/call-dirmngr.c15
-rw-r--r--tools/call-dirmngr.h15
-rw-r--r--tools/gpg-check-pattern.c2
-rw-r--r--tools/gpg-wks-client.c19
-rw-r--r--tools/gpg-wks-server.c79
-rw-r--r--tools/gpg-wks.h15
-rw-r--r--tools/gpgconf-comp.c14
-rw-r--r--tools/gpgconf.c3
-rw-r--r--tools/gpgsplit.c4
-rw-r--r--tools/mime-maker.c15
-rw-r--r--tools/mime-maker.h15
-rw-r--r--tools/mime-parser.c15
-rw-r--r--tools/mime-parser.h15
-rw-r--r--tools/rfc822parse.c20
-rw-r--r--tools/rfc822parse.h18
-rw-r--r--tools/send-mail.c15
-rw-r--r--tools/send-mail.h15
-rw-r--r--tools/symcryptrun.c2
-rw-r--r--tools/wks-receive.c15
-rw-r--r--tools/wks-util.c16
196 files changed, 11574 insertions, 5334 deletions
diff --git a/AUTHORS b/AUTHORS
index ec4b742..99bb0e2 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,6 +1,6 @@
Program: GnuPG
Homepage: https://www.gnupg.org
-Download: ftp://ftp.gnupg.org/gcrypt/gnupg/
+Download: https://gnupg.org/ftp/gcrypt/gnupg/
Repository: git://git.gnupg.org/gnupg.git
Bug reports: https://bugs.gnupg.org
Security related bug reports: <security@gnupg.org>
@@ -32,6 +32,7 @@ List of Copyright holders
Copyright (C) 1992-1996 Regents of the University of Michigan.
Copyright (C) 2000 Dimitrios Souflis
Copyright (C) 2008,2009,2010,2012-2016 William Ahern
+ Copyright (C) 2017 Bundesamt für Sicherheit in der Informationstechnik
Authors with a FSF copyright assignment
@@ -201,6 +202,9 @@ Tobias Mueller <muelli@cryptobitch.de>
Werner Koch <wk@gnupg.org>
2013-03-29:87620ahchj.fsf@vigenere.g10code.de:
+William L. Thomson Jr. <wlt@o-sinc.com>
+2017-05-23:assp.0316398ca8.20170523093623.00a17d03@o-sinc.com:
+
Yann E. MORIN <yann.morin.1998@free.fr>
2016-07-10:20160710093202.GA3688@free.fr:
@@ -234,19 +238,22 @@ The test driver is based on TinySCHEME by Dimitrios Souflis and
available under a permissive license; see COPYING.other.
-Copyright
-=========
+License
+========
GnuPG is distributed under the GNU General Public License, version 3
-or later.
+or later (see file COPYING).
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 files carry an all permissive license note as found at the
-bottom of this file. A few files are distributed under permissive
-licenses as listed in the file COPYING.other. Some other small files
-are distributed under the Creative Commons Zero license (see file
-COPYING.CC0) which basically puts them into the public domain.
+Public License, version 3 (see file COPYING.LGPL3) and the GNU General
+Public License, version 2 (see file COPYING.GPL2). Some files are
+under the GNU Lesser General Public License, version 2.1 (see file
+COPYING.LGPL21). A few files carry an all permissive license note as
+found at the bottom of this file. A few files are distributed under
+permissive licenses as listed in the file COPYING.other. Some other
+small files are distributed under the Creative Commons Zero license
+(see file COPYING.CC0) which basically puts them into the public
+domain.
=========
diff --git a/COPYING.GPL2 b/COPYING.GPL2
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/COPYING.GPL2
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/COPYING.LGPL21 b/COPYING.LGPL21
new file mode 100644
index 0000000..4ad3268
--- /dev/null
+++ b/COPYING.LGPL21
@@ -0,0 +1,509 @@
+[Note that only a few files are distributed under this license.]
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations
+below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+^L
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it
+becomes a de-facto standard. To achieve this, non-free programs must
+be allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+^L
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control
+compilation and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+^L
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+^L
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at least
+ three years, to give the same user the materials specified in
+ Subsection 6a, above, for a charge no more than the cost of
+ performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+^L
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+^L
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply, and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License
+may add an explicit geographical distribution limitation excluding those
+countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+^L
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+^L
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms
+of the ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library.
+It is safest to attach them to the start of each source file to most
+effectively convey the exclusion of warranty; and each file should
+have at least the "copyright" line and a pointer to where the full
+notice is found.
+
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.1 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
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or
+your school, if any, to sign a "copyright disclaimer" for the library,
+if necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James
+ Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/COPYING.LIB b/COPYING.LGPL3
index 4cd6920..4cd6920 100644
--- a/COPYING.LIB
+++ b/COPYING.LGPL3
diff --git a/Makefile.am b/Makefile.am
index e1f9a27..e31d67a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -28,7 +28,8 @@ GITLOG_TO_CHANGELOG=gitlog-to-changelog
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 \
- COPYING.CC0 COPYING.other \
+ COPYING.GPL2 COPYING.LGPL21 COPYING.LGPL3 \
+ COPYING.CC0 COPYING.other \
build-aux/git-log-fix build-aux/git-log-footer \
build-aux/getswdb.sh \
build-aux/speedo.mk \
diff --git a/NEWS b/NEWS
index 574f7da..c859eb4 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,46 @@
+Noteworthy changes in version 2.1.22 (2017-07-28)
+-------------------------------------------------
+
+ * gpg: Extend command --quick-set-expire to allow for setting the
+ expiration time of subkeys.
+
+ * gpg: By default try to repair keys during import. New sub-option
+ no-repair-keys for --import-options.
+
+ * gpg,gpgsm: Improved checking and reporting of DE-VS compliance.
+
+ * gpg: New options --key-origin and --with-key-origin. Store the
+ time of the last key update from keyservers, WKD, or DANE.
+
+ * agent: New option --ssh-fingerprint-digest.
+
+ * dimngr: Lower timeouts on keyserver connection attempts and made
+ it configurable.
+
+ * dirmngr: Tor will now automatically be detected and used. The
+ option --no-use-tor disables Tor detection.
+
+ * dirmngr: Now detects a changed /etc/resolv.conf.
+
+ * agent,dirmngr: Initiate shutdown on removal of the GnuPG home
+ directory.
+
+ * gpg: Avoid caching passphrase for failed symmetric encryption.
+
+ * agent: Support for unprotected ssh keys.
+
+ * dirmngr: Fixed name resolving on systems using only v6
+ nameservers.
+
+ * dirmngr: Allow the use of TLS over http proxies.
+
+ * w32: Change directory of the daemons after startup.
+
+ * wks: New man pages for client and server.
+
+ * Many other bug fixes.
+
+
Noteworthy changes in version 2.1.21 (2017-05-15)
-------------------------------------------------
@@ -9,8 +52,8 @@ Noteworthy changes in version 2.1.21 (2017-05-15)
system's standard methods for providing default configuration
files should be used instead.
- * w32: The Windows installer now allows installion of GnuPG without
- Administrator permissions.
+ * w32: The Windows installer now allows installation of GnuPG
+ without Administrator permissions.
* gpg: Fixed import filter property match bug.
@@ -3511,8 +3554,8 @@ Version 0.1.0 (1998-01-05)
Version 0.0.0 (1997-12-20)
- Copyright (C) 1998-2016 Free Software Foundation, Inc.
- Copyright (C) 1997-2016 Werner Koch
+ Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ Copyright (C) 1997-2017 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
diff --git a/README b/README
index 8be43d7..aaf347c 100644
--- a/README
+++ b/README
@@ -227,7 +227,7 @@
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
+ 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
diff --git a/agent/agent.h b/agent/agent.h
index 01e675b..815d9a5 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -167,6 +167,10 @@ struct
gpg-agent.c: If the value is less than 2 the name has not yet
been malloced. */
int browser_socket;
+
+ /* The digest algorithm to use for ssh fingerprints when
+ * communicating with the user. */
+ int ssh_fingerprint_digest;
} opt;
@@ -446,14 +450,14 @@ void agent_store_cache_hit (const char *key);
/*-- pksign.c --*/
-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,
- 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);
+gpg_error_t 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,
+ const void *overridedata, size_t overridedatalen);
+gpg_error_t 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,
@@ -478,7 +482,7 @@ unsigned char get_standard_s2k_count_rfc4880 (void);
int agent_protect (const unsigned char *plainkey, const char *passphrase,
unsigned char **result, size_t *resultlen,
unsigned long s2k_count, int use_ocb);
-int agent_unprotect (ctrl_t ctrl,
+gpg_error_t agent_unprotect (ctrl_t ctrl,
const unsigned char *protectedkey, const char *passphrase,
gnupg_isotime_t protected_at,
unsigned char **result, size_t *resultlen);
@@ -487,8 +491,8 @@ unsigned char *make_shadow_info (const char *serialno, const char *idstring);
int agent_shadow_key (const unsigned char *pubkey,
const unsigned char *shadow_info,
unsigned char **result);
-int agent_get_shadow_info (const unsigned char *shadowkey,
- unsigned char const **shadow_info);
+gpg_error_t 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, int *r_pinlen);
gpg_error_t s2k_hash_passphrase (const char *passphrase, int hashalgo,
diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c
index 1ff4059..6a5c1fe 100644
--- a/agent/call-pinentry.c
+++ b/agent/call-pinentry.c
@@ -167,6 +167,10 @@ unlock_pinentry (gpg_error_t rc)
case GPG_ERR_BAD_PIN:
break;
+ case GPG_ERR_CORRUPTED_PROTECTION:
+ /* This comes from gpg-agent. */
+ break;
+
default:
rc = gpg_err_make (GPG_ERR_SOURCE_PINENTRY, gpg_err_code (rc));
break;
@@ -489,7 +493,7 @@ start_pinentry (ctrl_t ctrl)
{
/* 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 what; } tbl[] = {
+ static const struct { const char *key, *value; int what; } 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
@@ -964,8 +968,8 @@ agent_askpin (ctrl_t ctrl,
size_t size;
*pininfo->pin = 0; /* Reset the PIN. */
- rc = pinentry_loopback(ctrl, "PASSPHRASE", &passphrase, &size,
- pininfo->max_length - 1);
+ rc = pinentry_loopback (ctrl, "PASSPHRASE", &passphrase, &size,
+ pininfo->max_length - 1);
if (rc)
return rc;
@@ -1192,10 +1196,10 @@ agent_get_passphrase (ctrl_t ctrl,
if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
{
size_t size;
- size_t len = ASSUAN_LINELENGTH/2;
return pinentry_loopback (ctrl, "PASSPHRASE",
- (unsigned char **)retpass, &size, len);
+ (unsigned char **)retpass, &size,
+ MAX_PASSPHRASE_LEN);
}
return gpg_error (GPG_ERR_NO_PIN_ENTRY);
}
diff --git a/agent/command-ssh.c b/agent/command-ssh.c
index 57e2e42..9d45a18 100644
--- a/agent/command-ssh.c
+++ b/agent/command-ssh.c
@@ -262,7 +262,7 @@ static gpg_error_t ssh_key_extract_comment (gcry_sexp_t key, char **comment);
/* Associating request types with the corresponding request
handlers. */
-static ssh_request_spec_t request_specs[] =
+static const ssh_request_spec_t request_specs[] =
{
#define REQUEST_SPEC_DEFINE(id, name, secret_input) \
{ SSH_REQUEST_##id, ssh_handler_##name, #name, secret_input }
@@ -280,7 +280,7 @@ static ssh_request_spec_t request_specs[] =
/* Table holding key type specifications. */
-static ssh_key_type_spec_t ssh_key_types[] =
+static const ssh_key_type_spec_t ssh_key_types[] =
{
{
"ssh-ed25519", "Ed25519", GCRY_PK_EDDSA, "qd", "q", "rs", "qd",
@@ -1040,12 +1040,14 @@ search_control_file (ssh_control_file_t cf, const char *hexgrip,
We can assume that the user wants to allow ssh using this key. */
static gpg_error_t
add_control_entry (ctrl_t ctrl, ssh_key_type_spec_t *spec,
- const char *hexgrip, const char *fmtfpr,
+ const char *hexgrip, gcry_sexp_t key,
int ttl, int confirm)
{
gpg_error_t err;
ssh_control_file_t cf;
int disabled;
+ char *fpr_md5 = NULL;
+ char *fpr_sha256 = NULL;
(void)ctrl;
@@ -1059,19 +1061,31 @@ add_control_entry (ctrl_t ctrl, ssh_key_type_spec_t *spec,
struct tm *tp;
time_t atime = time (NULL);
+ err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &fpr_md5);
+ if (err)
+ goto out;
+
+ err = ssh_get_fingerprint_string (key, GCRY_MD_SHA256, &fpr_sha256);
+ if (err)
+ goto out;
+
/* Not yet in the file - add it. Because the file has been
opened in append mode, we simply need to write to it. */
tp = localtime (&atime);
fprintf (cf->fp,
("# %s key added on: %04d-%02d-%02d %02d:%02d:%02d\n"
- "# MD5 Fingerprint: %s\n"
+ "# Fingerprints: %s\n"
+ "# %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":"");
+ fpr_md5, fpr_sha256, hexgrip, ttl, confirm? " confirm":"");
}
+ out:
+ xfree (fpr_md5);
+ xfree (fpr_sha256);
close_control_file (cf);
return 0;
}
@@ -2760,7 +2774,7 @@ data_sign (ctrl_t ctrl, ssh_key_type_spec_t *spec,
err = agent_raw_key_from_file (ctrl, ctrl->keygrip, &key);
if (err)
goto out;
- err = ssh_get_fingerprint_string (key, &fpr);
+ err = ssh_get_fingerprint_string (key, opt.ssh_fingerprint_digest, &fpr);
if (!err)
{
gcry_sexp_t tmpsxp = gcry_sexp_find_token (key, "comment", 0);
@@ -2966,6 +2980,7 @@ ssh_key_extract_comment (gcry_sexp_t key, char **r_comment)
/* This function converts the key contained in the S-Expression KEY
into a buffer, which is protected by the passphrase PASSPHRASE.
+ If PASSPHRASE is the empty passphrase, the key is not protected.
Returns usual error code. */
static gpg_error_t
ssh_key_to_protected_buffer (gcry_sexp_t key, const char *passphrase,
@@ -2986,7 +3001,17 @@ 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, 0, -1);
+ if (*passphrase)
+ err = agent_protect (buffer_new, passphrase, buffer, buffer_n, 0, -1);
+ else
+ {
+ /* The key derivation function does not support zero length
+ * strings. Store key unprotected if the user wishes so. */
+ *buffer = buffer_new;
+ *buffer_n = buffer_new_n;
+ buffer_new = NULL;
+ err = 0;
+ }
out:
@@ -3038,7 +3063,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
bin2hex (key_grip_raw, 20, key_grip);
- err = ssh_get_fingerprint_string (key, &key_fpr);
+ err = ssh_get_fingerprint_string (key, opt.ssh_fingerprint_digest, &key_fpr);
if (err)
goto out;
@@ -3118,7 +3143,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
key_exists:
/* And add an entry to the sshcontrol file. */
- err = add_control_entry (ctrl, spec, key_grip, key_fpr, ttl, confirm);
+ err = add_control_entry (ctrl, spec, key_grip, key, ttl, confirm);
out:
@@ -3376,10 +3401,10 @@ ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response)
/* Return the request specification for the request identified by TYPE
or NULL in case the requested request specification could not be
found. */
-static ssh_request_spec_t *
+static const ssh_request_spec_t *
request_spec_lookup (int type)
{
- ssh_request_spec_t *spec;
+ const ssh_request_spec_t *spec;
unsigned int i;
for (i = 0; i < DIM (request_specs); i++)
@@ -3403,7 +3428,7 @@ request_spec_lookup (int type)
static int
ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
{
- ssh_request_spec_t *spec;
+ const ssh_request_spec_t *spec;
estream_t response = NULL;
estream_t request = NULL;
unsigned char request_type;
@@ -3682,7 +3707,7 @@ serve_mmapped_ssh_request (ctrl_t ctrl,
gpg_error_t err;
int send_err = 0;
int valid_response = 0;
- ssh_request_spec_t *spec;
+ const ssh_request_spec_t *spec;
u32 msglen;
estream_t request_stream, response_stream;
diff --git a/agent/command.c b/agent/command.c
index df788ef..f2a6683 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -782,7 +782,7 @@ static const char hlp_pksign[] =
static gpg_error_t
cmd_pksign (assuan_context_t ctx, char *line)
{
- int rc;
+ gpg_error_t err;
cache_mode_t cache_mode = CACHE_MODE_NORMAL;
ctrl_t ctrl = assuan_get_pointer (ctx);
membuf_t outbuf;
@@ -804,17 +804,17 @@ cmd_pksign (assuan_context_t ctx, char *line)
init_membuf (&outbuf, 512);
- rc = agent_pksign (ctrl, cache_nonce, ctrl->server_local->keydesc,
- &outbuf, cache_mode);
- if (rc)
+ err = agent_pksign (ctrl, cache_nonce, ctrl->server_local->keydesc,
+ &outbuf, cache_mode);
+ if (err)
clear_outbuf (&outbuf);
else
- rc = write_and_clear_outbuf (ctx, &outbuf);
+ err = write_and_clear_outbuf (ctx, &outbuf);
xfree (cache_nonce);
xfree (ctrl->server_local->keydesc);
ctrl->server_local->keydesc = NULL;
- return leave_cmd (ctx, rc);
+ return leave_cmd (ctx, err);
}
@@ -1201,7 +1201,7 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
if (!agent_raw_key_from_file (ctrl, grip, &key))
{
- ssh_get_fingerprint_string (key, &fpr);
+ ssh_get_fingerprint_string (key, GCRY_MD_MD5, &fpr);
gcry_sexp_release (key);
}
}
@@ -2852,6 +2852,7 @@ static const char hlp_getinfo[] =
" cmd_has_option\n"
" - Returns OK if the command CMD implements the option OPT.\n"
" connections - Return number of active connections.\n"
+ " jent_active - Returns OK if Libgcrypt's JENT is active.\n"
" restricted - Returns OK if the connection is in restricted mode.\n";
static gpg_error_t
cmd_getinfo (assuan_context_t ctx, char *line)
@@ -2992,6 +2993,24 @@ cmd_getinfo (assuan_context_t ctx, char *line)
get_agent_active_connection_count ());
rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
}
+ else if (!strcmp (line, "jent_active"))
+ {
+#if GCRYPT_VERSION_NUMBER >= 0x010800
+ char *buf;
+ char *fields[5];
+
+ buf = gcry_get_config (0, "rng-type");
+ if (buf
+ && split_fields_colon (buf, fields, DIM (fields)) >= 5
+ && atoi (fields[4]) > 0)
+ rc = 0;
+ else
+ rc = gpg_error (GPG_ERR_FALSE);
+ gcry_free (buf);
+#else
+ rc = gpg_error (GPG_ERR_FALSE);
+#endif
+ }
else
rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
return rc;
diff --git a/agent/divert-scd.c b/agent/divert-scd.c
index 153119b..88b35cd 100644
--- a/agent/divert-scd.c
+++ b/agent/divert-scd.c
@@ -52,6 +52,7 @@ ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid)
{
rc = gpg_error_from_syserror ();
xfree (want_sn);
+ xfree (want_kid);
return rc;
}
@@ -84,6 +85,7 @@ ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid)
serialno = NULL;
if (!i)
{
+ xfree (want_sn_disp);
xfree (want_sn);
*r_kid = want_kid;
return 0; /* yes, we have the correct card */
@@ -122,9 +124,9 @@ 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);
+ 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);
}
diff --git a/agent/findkey.c b/agent/findkey.c
index b24d8f1..e3e9a12 100644
--- a/agent/findkey.c
+++ b/agent/findkey.c
@@ -412,7 +412,8 @@ agent_modify_description (const char *in, const char *comment,
case 'F': /* SSH style fingerprint. */
if (!ssh_fpr && key)
- ssh_get_fingerprint_string (key, &ssh_fpr);
+ ssh_get_fingerprint_string (key, opt.ssh_fingerprint_digest,
+ &ssh_fpr);
if (ssh_fpr)
{
if (out)
@@ -487,7 +488,7 @@ agent_modify_description (const char *in, const char *comment,
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
+static gpg_error_t
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,
@@ -689,7 +690,7 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
static gpg_error_t
read_key_file (const unsigned char *grip, gcry_sexp_t *result)
{
- int rc;
+ gpg_error_t err;
char *fname;
estream_t fp;
struct stat st;
@@ -709,30 +710,30 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result)
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));
+ err = gpg_error_from_syserror ();
+ if (gpg_err_code (err) != GPG_ERR_ENOENT)
+ log_error ("can't open '%s': %s\n", fname, gpg_strerror (err));
xfree (fname);
- return rc;
+ return err;
}
if (es_fread (&first, 1, 1, fp) != 1)
{
- rc = gpg_error_from_syserror ();
+ err = gpg_error_from_syserror ();
log_error ("error reading first byte from '%s': %s\n",
- fname, strerror (errno));
+ fname, gpg_strerror (err));
xfree (fname);
es_fclose (fp);
- return rc;
+ return err;
}
- rc = es_fseek (fp, 0, SEEK_SET);
- if (rc)
+ if (es_fseek (fp, 0, SEEK_SET))
{
- log_error ("error seeking in '%s': %s\n", fname, strerror (errno));
+ err = gpg_error_from_syserror ();
+ log_error ("error seeking in '%s': %s\n", fname, gpg_strerror (err));
xfree (fname);
es_fclose (fp);
- return rc;
+ return err;
}
if (first != '(')
@@ -741,69 +742,69 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result)
nvc_t pk;
int line;
- rc = nvc_parse_private_key (&pk, &line, fp);
+ err = nvc_parse_private_key (&pk, &line, fp);
es_fclose (fp);
- if (rc)
+ if (err)
log_error ("error parsing '%s' line %d: %s\n",
- fname, line, gpg_strerror (rc));
+ fname, line, gpg_strerror (err));
else
{
- rc = nvc_get_private_key (pk, result);
+ err = nvc_get_private_key (pk, result);
nvc_release (pk);
- if (rc)
+ if (err)
log_error ("error getting private key from '%s': %s\n",
- fname, gpg_strerror (rc));
+ fname, gpg_strerror (err));
}
xfree (fname);
- return rc;
+ return err;
}
if (fstat (es_fileno (fp), &st))
{
- rc = gpg_error_from_syserror ();
- log_error ("can't stat '%s': %s\n", fname, strerror (errno));
+ err = gpg_error_from_syserror ();
+ log_error ("can't stat '%s': %s\n", fname, gpg_strerror (err));
xfree (fname);
es_fclose (fp);
- return rc;
+ return err;
}
buflen = st.st_size;
buf = xtrymalloc (buflen+1);
if (!buf)
{
- rc = gpg_error_from_syserror ();
+ err = gpg_error_from_syserror ();
log_error ("error allocating %zu bytes for '%s': %s\n",
- buflen, fname, strerror (errno));
+ buflen, fname, gpg_strerror (err));
xfree (fname);
es_fclose (fp);
xfree (buf);
- return rc;
+ return err;
}
if (es_fread (buf, buflen, 1, fp) != 1)
{
- rc = gpg_error_from_syserror ();
+ err = gpg_error_from_syserror ();
log_error ("error reading %zu bytes from '%s': %s\n",
- buflen, fname, strerror (errno));
+ buflen, fname, gpg_strerror (err));
xfree (fname);
es_fclose (fp);
xfree (buf);
- return rc;
+ return err;
}
/* Convert the file into a gcrypt S-expression object. */
- rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
+ err = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
xfree (fname);
es_fclose (fp);
xfree (buf);
- if (rc)
+ if (err)
{
log_error ("failed to build S-Exp (off=%u): %s\n",
- (unsigned int)erroff, gpg_strerror (rc));
- return rc;
+ (unsigned int)erroff, gpg_strerror (err));
+ return err;
}
*result = s_skey;
return 0;
@@ -851,7 +852,7 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
gcry_sexp_t *result, char **r_passphrase)
{
- int rc;
+ gpg_error_t err;
unsigned char *buf;
size_t len, buflen, erroff;
gcry_sexp_t s_skey;
@@ -862,20 +863,20 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
if (r_passphrase)
*r_passphrase = NULL;
- rc = read_key_file (grip, &s_skey);
- if (rc)
+ err = read_key_file (grip, &s_skey);
+ if (err)
{
- if (gpg_err_code (rc) == GPG_ERR_ENOENT)
- rc = gpg_error (GPG_ERR_NO_SECKEY);
- return rc;
+ if (gpg_err_code (err) == GPG_ERR_ENOENT)
+ err = gpg_error (GPG_ERR_NO_SECKEY);
+ return err;
}
/* For use with the protection functions we also need the key as an
canonical encoded S-expression in a buffer. Create this buffer
now. */
- rc = make_canon_sexp (s_skey, &buf, &len);
- if (rc)
- return rc;
+ err = make_canon_sexp (s_skey, &buf, &len);
+ if (err)
+ return err;
switch (agent_private_key_type (buf))
{
@@ -886,10 +887,10 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
unsigned char *buf_new;
size_t buf_newlen;
- rc = agent_unprotect (ctrl, buf, "", NULL, &buf_new, &buf_newlen);
- if (rc)
+ err = agent_unprotect (ctrl, buf, "", NULL, &buf_new, &buf_newlen);
+ if (err)
log_error ("failed to convert unprotected openpgp key: %s\n",
- gpg_strerror (rc));
+ gpg_strerror (err));
else
{
xfree (buf);
@@ -916,17 +917,17 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
desc_text_final = NULL;
if (desc_text)
- rc = agent_modify_description (desc_text, comment, s_skey,
- &desc_text_final);
+ err = agent_modify_description (desc_text, comment, s_skey,
+ &desc_text_final);
gcry_free (comment);
- if (!rc)
+ if (!err)
{
- rc = unprotect (ctrl, cache_nonce, desc_text_final, &buf, grip,
+ err = unprotect (ctrl, cache_nonce, desc_text_final, &buf, grip,
cache_mode, lookup_ttl, r_passphrase);
- if (rc)
+ if (err)
log_error ("failed to unprotect the secret key: %s\n",
- gpg_strerror (rc));
+ gpg_strerror (err));
}
xfree (desc_text_final);
@@ -938,34 +939,34 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
const unsigned char *s;
size_t n;
- rc = agent_get_shadow_info (buf, &s);
- if (!rc)
+ err = agent_get_shadow_info (buf, &s);
+ if (!err)
{
n = gcry_sexp_canon_len (s, 0, NULL,NULL);
- assert (n);
+ log_assert (n);
*shadow_info = xtrymalloc (n);
if (!*shadow_info)
- rc = out_of_core ();
+ err = out_of_core ();
else
{
memcpy (*shadow_info, s, n);
- rc = 0;
+ err = 0;
}
}
- if (rc)
- log_error ("get_shadow_info failed: %s\n", gpg_strerror (rc));
+ if (err)
+ log_error ("get_shadow_info failed: %s\n", gpg_strerror (err));
}
else
- rc = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
+ err = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
break;
default:
log_error ("invalid private key format\n");
- rc = gpg_error (GPG_ERR_BAD_SECKEY);
+ err = gpg_error (GPG_ERR_BAD_SECKEY);
break;
}
gcry_sexp_release (s_skey);
s_skey = NULL;
- if (rc)
+ if (err)
{
xfree (buf);
if (r_passphrase)
@@ -973,23 +974,23 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
xfree (*r_passphrase);
*r_passphrase = NULL;
}
- return rc;
+ return err;
}
buflen = gcry_sexp_canon_len (buf, 0, NULL, NULL);
- rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
+ err = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
wipememory (buf, buflen);
xfree (buf);
- if (rc)
+ if (err)
{
log_error ("failed to build S-Exp (off=%u): %s\n",
- (unsigned int)erroff, gpg_strerror (rc));
+ (unsigned int)erroff, gpg_strerror (err));
if (r_passphrase)
{
xfree (*r_passphrase);
*r_passphrase = NULL;
}
- return rc;
+ return err;
}
*result = s_skey;
diff --git a/agent/genkey.c b/agent/genkey.c
index 31742a1..a3e37ee 100644
--- a/agent/genkey.c
+++ b/agent/genkey.c
@@ -357,10 +357,10 @@ agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
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);
+ err = pinentry_loopback (ctrl, "NEW_PASSPHRASE", &buffer, &size,
+ MAX_PASSPHRASE_LEN);
if (!err)
{
if (size)
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index c764be8..603f707 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -129,6 +129,7 @@ enum cmd_and_opt_values
oKeepTTY,
oKeepDISPLAY,
oSSHSupport,
+ oSSHFingerprintDigest,
oPuttySupport,
oDisableScdaemon,
oDisableCheckOwnSocket,
@@ -163,7 +164,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_s (oDebug, "debug", "@"),
ARGPARSE_s_n (oDebugAll, "debug-all", "@"),
ARGPARSE_s_s (oDebugLevel, "debug-level", "@"),
- ARGPARSE_s_i (oDebugWait," debug-wait", "@"),
+ ARGPARSE_s_i (oDebugWait, "debug-wait", "@"),
ARGPARSE_s_n (oDebugQuickRandom, "debug-quick-random", "@"),
ARGPARSE_s_n (oDebugPinentry, "debug-pinentry", "@"),
@@ -232,6 +233,8 @@ static ARGPARSE_OPTS opts[] = {
/* */ N_("allow passphrase to be prompted through Emacs")),
ARGPARSE_s_n (oSSHSupport, "enable-ssh-support", N_("enable ssh support")),
+ ARGPARSE_s_s (oSSHFingerprintDigest, "ssh-fingerprint-digest",
+ N_("|ALGO|use ALGO to show ssh fingerprints")),
ARGPARSE_s_n (oPuttySupport, "enable-putty-support",
#ifdef HAVE_W32_SYSTEM
/* */ N_("enable putty support")
@@ -246,7 +249,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oUseStandardSocket, "use-standard-socket", "@"),
ARGPARSE_s_n (oNoUseStandardSocket, "no-use-standard-socket", "@"),
- {0} /* End of list */
+ ARGPARSE_end () /* End of list */
};
@@ -273,19 +276,17 @@ static struct debug_flags_s debug_flags [] =
#define MIN_PASSPHRASE_NONALPHA (1)
#define MAX_PASSPHRASE_DAYS (0)
-/* 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. 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. */
+/* The timer tick used for housekeeping stuff. Note that on Windows
+ * we use a SetWaitableTimer seems to signal earlier than about 2
+ * seconds. Thus we use 4 seconds on all platforms except for
+ * Windowsce. 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)
+# define TIMERTICK_INTERVAL (4)
# define CHECK_OWN_SOCKET_INTERVAL (60)
#endif
@@ -379,10 +380,20 @@ static const char *debug_level;
static char *current_logfile;
/* The handle_tick() function may test whether a parent is still
- running. We record the PID of the parent here or -1 if it should be
- watched. */
+ * running. We record the PID of the parent here or -1 if it should
+ * be watched. */
static pid_t parent_pid = (pid_t)(-1);
+/* This flag is true if the inotify mechanism for detecting the
+ * removal of the homedir is active. This flag is used to disable the
+ * alternative but portable stat based check. */
+static int have_homedir_inotify;
+
+/* Depending on how gpg-agent was started, the homedir inotify watch
+ * may not be reliable. This flag is set if we assume that inotify
+ * works reliable. */
+static int reliable_homedir_inotify;
+
/* Number of active connections. */
static int active_connections;
@@ -769,6 +780,8 @@ cleanup (void)
static int
parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
{
+ int i;
+
if (!pargs)
{ /* reset mode */
opt.quiet = 0;
@@ -800,6 +813,8 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
opt.allow_emacs_pinentry = 0;
opt.disable_scdaemon = 0;
disable_check_own_socket = 0;
+ /* Note: When changing the next line, change also gpgconf_list. */
+ opt.ssh_fingerprint_digest = GCRY_MD_MD5;
return 1;
}
@@ -882,6 +897,14 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
case oAllowEmacsPinentry: opt.allow_emacs_pinentry = 1;
break;
+ case oSSHFingerprintDigest:
+ i = gcry_md_map_name (pargs->r.ret_str);
+ if (!i)
+ log_error (_("selected digest algorithm is invalid\n"));
+ else
+ opt.ssh_fingerprint_digest = i;
+ break;
+
default:
return 0; /* not handled */
}
@@ -1176,6 +1199,7 @@ main (int argc, char **argv )
case oSSHSupport:
ssh_support = 1;
break;
+
case oPuttySupport:
# ifdef HAVE_W32_SYSTEM
putty_support = 1;
@@ -1369,6 +1393,8 @@ main (int argc, char **argv )
es_printf ("disable-scdaemon:%lu:\n",
GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME);
es_printf ("enable-ssh-support:%lu:\n", GC_OPT_FLAG_NONE);
+ es_printf ("ssh-fingerprint-digest:%lu:\"%s:\n",
+ GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, "md5");
#ifdef HAVE_W32_SYSTEM
es_printf ("enable-putty-support:%lu:\n", GC_OPT_FLAG_NONE);
#endif
@@ -1697,12 +1723,12 @@ main (int argc, char **argv )
log_get_prefix (&oldflags);
log_set_prefix (NULL, oldflags | GPGRT_LOG_RUN_DETACHED);
opt.running_detached = 1;
- }
- if (chdir("/"))
- {
- log_error ("chdir to / failed: %s\n", strerror (errno));
- exit (1);
+ /* Unless we are running with a program given on the command
+ * line we can assume that the inotify things works and thus
+ * we can avoid tye regular stat calls. */
+ if (!argc)
+ reliable_homedir_inotify = 1;
}
{
@@ -1715,6 +1741,13 @@ main (int argc, char **argv )
}
#endif /*!HAVE_W32_SYSTEM*/
+ if (gnupg_chdir (gnupg_daemon_rootdir ()))
+ {
+ log_error ("chdir to '%s' failed: %s\n",
+ gnupg_daemon_rootdir (), strerror (errno));
+ exit (1);
+ }
+
log_info ("%s %s started\n", strusage(11), strusage(13) );
handle_connections (fd, fd_extra, fd_browser, fd_ssh);
assuan_sock_close (fd);
@@ -1911,7 +1944,7 @@ agent_copy_startup_env (ctrl_t ctrl)
const char *value;
for (idx=0; !err && names[idx]; idx++)
- if ((value = session_env_getenv (opt.startup_env, names[idx])))
+ if ((value = session_env_getenv (opt.startup_env, names[idx])))
err = session_env_setenv (ctrl->session_env, names[idx], value);
if (!err && !ctrl->lc_ctype && opt.startup_lc_ctype)
@@ -2120,6 +2153,7 @@ create_server_socket (char *name, int primary, int cygwin,
log_error ("error preparing socket '%s': %s\n",
name, gpg_strerror (gpg_error_from_syserror ()));
*name = 0; /* Inhibit removal of the socket by cleanup(). */
+ xfree (unaddr);
agent_exit (2);
}
if (redirected)
@@ -2157,6 +2191,7 @@ create_server_socket (char *name, int primary, int cygwin,
"not starting a new one\n"));
*name = 0; /* Inhibit removal of the socket by cleanup(). */
assuan_sock_close (fd);
+ xfree (unaddr);
agent_exit (2);
}
gnupg_remove (unaddr->sun_path);
@@ -2169,11 +2204,12 @@ create_server_socket (char *name, int primary, int cygwin,
/* 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"),
- unaddr->sun_path,
+ unaddr->sun_path,
gpg_strerror (gpg_error_from_syserror ()));
assuan_sock_close (fd);
*name = 0; /* Inhibit removal of the socket by cleanup(). */
+ xfree (unaddr);
agent_exit (2);
}
@@ -2186,12 +2222,14 @@ create_server_socket (char *name, int primary, int cygwin,
log_error (_("listen() failed: %s\n"), strerror (errno));
*name = 0; /* Inhibit removal of the socket by cleanup(). */
assuan_sock_close (fd);
+ xfree (unaddr);
agent_exit (2);
}
if (opt.verbose)
log_info (_("listening on socket '%s'\n"), unaddr->sun_path);
+ xfree (unaddr);
return fd;
}
@@ -2284,6 +2322,7 @@ static void
handle_tick (void)
{
static time_t last_minute;
+ struct stat statbuf;
if (!last_minute)
last_minute = time (NULL);
@@ -2316,6 +2355,14 @@ handle_tick (void)
}
#endif
+ /* Check whether the homedir is still available. */
+ if (!shutdown_pending
+ && (!have_homedir_inotify || !reliable_homedir_inotify)
+ && stat (gnupg_homedir (), &statbuf) && errno == ENOENT)
+ {
+ shutdown_pending = 1;
+ log_info ("homedir has been removed - shutting down\n");
+ }
}
@@ -2736,7 +2783,8 @@ handle_connections (gnupg_fd_t listen_fd,
HANDLE events[2];
unsigned int events_set;
#endif
- int my_inotify_fd = -1;
+ int sock_inotify_fd = -1;
+ int home_inotify_fd = -1;
struct {
const char *name;
void *(*func) (void *arg);
@@ -2775,14 +2823,26 @@ handle_connections (gnupg_fd_t listen_fd,
#endif
if (disable_check_own_socket)
- my_inotify_fd = -1;
- else if ((err = gnupg_inotify_watch_socket (&my_inotify_fd, socket_name)))
+ sock_inotify_fd = -1;
+ else if ((err = gnupg_inotify_watch_socket (&sock_inotify_fd, socket_name)))
{
if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED)
- log_info ("error enabling fast daemon termination: %s\n",
+ log_info ("error enabling daemon termination by socket removal: %s\n",
gpg_strerror (err));
}
+ if (disable_check_own_socket)
+ home_inotify_fd = -1;
+ else if ((err = gnupg_inotify_watch_delete_self (&home_inotify_fd,
+ gnupg_homedir ())))
+ {
+ if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED)
+ log_info ("error enabling daemon termination by homedir removal: %s\n",
+ gpg_strerror (err));
+ }
+ else
+ have_homedir_inotify = 1;
+
/* 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
Pageant (its ssh-agent implementation). */
@@ -2824,11 +2884,17 @@ handle_connections (gnupg_fd_t listen_fd,
if (FD2INT (listen_fd_ssh) > nfd)
nfd = FD2INT (listen_fd_ssh);
}
- if (my_inotify_fd != -1)
+ if (sock_inotify_fd != -1)
{
- FD_SET (my_inotify_fd, &fdset);
- if (my_inotify_fd > nfd)
- nfd = my_inotify_fd;
+ FD_SET (sock_inotify_fd, &fdset);
+ if (sock_inotify_fd > nfd)
+ nfd = sock_inotify_fd;
+ }
+ if (home_inotify_fd != -1)
+ {
+ FD_SET (home_inotify_fd, &fdset);
+ if (home_inotify_fd > nfd)
+ nfd = home_inotify_fd;
}
listentbl[0].l_fd = listen_fd;
@@ -2856,10 +2922,16 @@ handle_connections (gnupg_fd_t listen_fd,
* intention of a shutdown. */
FD_ZERO (&fdset);
nfd = -1;
- if (my_inotify_fd != -1)
+ if (sock_inotify_fd != -1)
+ {
+ FD_SET (sock_inotify_fd, &fdset);
+ nfd = sock_inotify_fd;
+ }
+ if (home_inotify_fd != -1)
{
- FD_SET (my_inotify_fd, &fdset);
- nfd = my_inotify_fd;
+ FD_SET (home_inotify_fd, &fdset);
+ if (home_inotify_fd > nfd)
+ nfd = home_inotify_fd;
}
}
@@ -2915,14 +2987,21 @@ handle_connections (gnupg_fd_t listen_fd,
ctrl_t ctrl;
npth_t thread;
- if (my_inotify_fd != -1
- && FD_ISSET (my_inotify_fd, &read_fdset)
- && gnupg_inotify_has_name (my_inotify_fd, GPG_AGENT_SOCK_NAME))
+ if (sock_inotify_fd != -1
+ && FD_ISSET (sock_inotify_fd, &read_fdset)
+ && gnupg_inotify_has_name (sock_inotify_fd, GPG_AGENT_SOCK_NAME))
{
shutdown_pending = 1;
log_info ("socket file has been removed - shutting down\n");
}
+ if (home_inotify_fd != -1
+ && FD_ISSET (home_inotify_fd, &read_fdset))
+ {
+ shutdown_pending = 1;
+ log_info ("homedir has been removed - shutting down\n");
+ }
+
for (idx=0; idx < DIM(listentbl); idx++)
{
if (listentbl[idx].l_fd == GNUPG_INVALID_FD)
@@ -2968,8 +3047,10 @@ handle_connections (gnupg_fd_t listen_fd,
}
}
- if (my_inotify_fd != -1)
- close (my_inotify_fd);
+ if (sock_inotify_fd != -1)
+ close (sock_inotify_fd);
+ if (home_inotify_fd != -1)
+ close (home_inotify_fd);
cleanup ();
log_info (_("%s %s stopped\n"), strusage(11), strusage(13));
npth_attr_destroy (&tattr);
diff --git a/agent/pksign.c b/agent/pksign.c
index 8faf4a4..f54af08 100644
--- a/agent/pksign.c
+++ b/agent/pksign.c
@@ -271,26 +271,26 @@ do_encode_raw_pkcs1 (const byte *md, size_t mdlen, unsigned int nbits,
/* 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. 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 does the hashing itself. */
-int
+ * the signature S-expression. LOOKUP is an optional function to
+ * 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 does the hashing itself. */
+gpg_error_t
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,
const void *overridedata, size_t overridedatalen)
{
+ gpg_error_t err = 0;
gcry_sexp_t s_skey = NULL;
gcry_sexp_t s_sig = NULL;
gcry_sexp_t s_hash = NULL;
gcry_sexp_t s_pkey = NULL;
unsigned char *shadow_info = NULL;
- unsigned int rc = 0; /* FIXME: gpg-error? */
const unsigned char *data;
int datalen;
int check_signature = 0;
@@ -309,12 +309,12 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
if (!ctrl->have_keygrip)
return gpg_error (GPG_ERR_NO_SECKEY);
- rc = agent_key_from_file (ctrl, cache_nonce, desc_text, ctrl->keygrip,
- &shadow_info, cache_mode, lookup_ttl,
- &s_skey, NULL);
- if (rc)
+ err = agent_key_from_file (ctrl, cache_nonce, desc_text, ctrl->keygrip,
+ &shadow_info, cache_mode, lookup_ttl,
+ &s_skey, NULL);
+ if (err)
{
- if (gpg_err_code (rc) != GPG_ERR_NO_SECKEY)
+ if (gpg_err_code (err) != GPG_ERR_NO_SECKEY)
log_error ("failed to read the secret key\n");
goto leave;
}
@@ -329,8 +329,8 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
int is_ECDSA = 0;
int is_EdDSA = 0;
- rc = agent_public_key_from_file (ctrl, ctrl->keygrip, &s_pkey);
- if (rc)
+ err = agent_public_key_from_file (ctrl, ctrl->keygrip, &s_pkey);
+ if (err)
{
log_error ("failed to read the public key\n");
goto leave;
@@ -353,15 +353,15 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
if (desc_text)
agent_modify_description (desc_text, NULL, s_skey, &desc2);
- rc = divert_pksign (ctrl, desc2? desc2 : desc_text,
- data, datalen,
- ctrl->digest.algo,
- shadow_info, &buf, &len);
+ err = divert_pksign (ctrl, desc2? desc2 : desc_text,
+ data, datalen,
+ ctrl->digest.algo,
+ shadow_info, &buf, &len);
xfree (desc2);
}
- if (rc)
+ if (err)
{
- log_error ("smartcard signing failed: %s\n", gpg_strerror (rc));
+ log_error ("smartcard signing failed: %s\n", gpg_strerror (err));
goto leave;
}
@@ -379,13 +379,13 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
*buf = 0;
}
- rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s%b)))",
- (int)len, buf);
+ err = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s%b)))",
+ (int)len, buf);
}
else if (is_EdDSA)
{
- rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(eddsa(r%b)(s%b)))",
- (int)len/2, buf, (int)len/2, buf + len/2);
+ err = gcry_sexp_build (&s_sig, NULL, "(sig-val(eddsa(r%b)(s%b)))",
+ (int)len/2, buf, (int)len/2, buf + len/2);
}
else if (is_ECDSA)
{
@@ -401,7 +401,10 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
r_buflen++;
r_buf_allocated = xtrymalloc (r_buflen);
if (!r_buf_allocated)
- goto leave;
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
r_buf = r_buf_allocated;
memcpy (r_buf + 1, buf, len/2);
@@ -416,6 +419,7 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
s_buf_allocated = xtrymalloc (s_buflen);
if (!s_buf_allocated)
{
+ err = gpg_error_from_syserror ();
xfree (r_buf_allocated);
goto leave;
}
@@ -427,20 +431,20 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
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);
+ err = 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);
+ err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
xfree (buf);
- if (rc)
+ if (err)
{
log_error ("failed to convert sigbuf returned by divert_pksign "
- "into S-Exp: %s", gpg_strerror (rc));
+ "into S-Exp: %s", gpg_strerror (err));
goto leave;
}
}
@@ -451,27 +455,29 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
/* Put the hash into a sexp */
if (agent_is_eddsa_key (s_skey))
- rc = do_encode_eddsa (data, datalen,
- &s_hash);
+ err = 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);
+ err = 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);
+ err = do_encode_dsa (data, datalen,
+ dsaalgo, s_skey,
+ &s_hash);
else
- rc = do_encode_md (data, datalen,
- ctrl->digest.algo,
- &s_hash,
- ctrl->digest.raw_value);
- if (rc)
+ err = do_encode_md (data, datalen,
+ ctrl->digest.algo,
+ &s_hash,
+ ctrl->digest.raw_value);
+ if (err)
goto leave;
if (dsaalgo == 0 && GCRYPT_VERSION_NUMBER < 0x010700)
- /* It's RSA and Libgcrypt < 1.7 */
- check_signature = 1;
+ {
+ /* It's RSA and Libgcrypt < 1.7 */
+ check_signature = 1;
+ }
if (DBG_CRYPTO)
{
@@ -480,10 +486,10 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
}
/* sign */
- rc = gcry_pk_sign (&s_sig, s_hash, s_skey);
- if (rc)
+ err = gcry_pk_sign (&s_sig, s_hash, s_skey);
+ if (err)
{
- log_error ("signing failed: %s\n", gpg_strerror (rc));
+ log_error ("signing failed: %s\n", gpg_strerror (err));
goto leave;
}
@@ -502,20 +508,20 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
if (s_hash == NULL)
{
if (ctrl->digest.algo == MD_USER_TLS_MD5SHA1)
- rc = do_encode_raw_pkcs1 (data, datalen,
- gcry_pk_get_nbits (sexp_key), &s_hash);
+ err = do_encode_raw_pkcs1 (data, datalen,
+ gcry_pk_get_nbits (sexp_key), &s_hash);
else
- rc = do_encode_md (data, datalen, ctrl->digest.algo, &s_hash,
- ctrl->digest.raw_value);
+ err = do_encode_md (data, datalen, ctrl->digest.algo, &s_hash,
+ ctrl->digest.raw_value);
}
- if (! rc)
- rc = gcry_pk_verify (s_sig, s_hash, sexp_key);
+ if (!err)
+ err = gcry_pk_verify (s_sig, s_hash, sexp_key);
- if (rc)
+ if (err)
{
log_error (_("checking created signature failed: %s\n"),
- gpg_strerror (rc));
+ gpg_strerror (err));
gcry_sexp_release (s_sig);
s_sig = NULL;
}
@@ -530,37 +536,42 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
gcry_sexp_release (s_hash);
xfree (shadow_info);
- return rc;
+ return err;
}
+
/* SIGN whatever information we have accumulated in CTRL and write it
- back to OUTFP. If a CACHE_NONCE is given that cache item is first
- tried to get a passphrase. */
-int
+ * back to OUTFP. If a CACHE_NONCE is given that cache item is first
+ * tried to get a passphrase. */
+gpg_error_t
agent_pksign (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
membuf_t *outbuf, cache_mode_t cache_mode)
{
+ gpg_error_t err;
gcry_sexp_t s_sig = NULL;
char *buf = NULL;
size_t len = 0;
- int rc = 0;
- rc = agent_pksign_do (ctrl, cache_nonce, desc_text, &s_sig, cache_mode, NULL,
- NULL, 0);
- if (rc)
+ err = agent_pksign_do (ctrl, cache_nonce, desc_text, &s_sig, cache_mode,
+ NULL, NULL, 0);
+ if (err)
goto leave;
len = gcry_sexp_sprint (s_sig, GCRYSEXP_FMT_CANON, NULL, 0);
- assert (len);
- buf = xmalloc (len);
+ log_assert (len);
+ buf = xtrymalloc (len);
+ if (!buf)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
len = gcry_sexp_sprint (s_sig, GCRYSEXP_FMT_CANON, buf, len);
- assert (len);
-
+ log_assert (len);
put_membuf (outbuf, buf, len);
leave:
gcry_sexp_release (s_sig);
xfree (buf);
- return rc;
+ return err;
}
diff --git a/agent/preset-passphrase.c b/agent/preset-passphrase.c
index 3d240b9..7a9ea1b 100644
--- a/agent/preset-passphrase.c
+++ b/agent/preset-passphrase.c
@@ -78,7 +78,8 @@ static ARGPARSE_OPTS opts[] = {
{ oForget, "forget", 256, "forget passphrase"},
{ oHomedir, "homedir", 2, "@" },
- {0}
+
+ ARGPARSE_end ()
};
diff --git a/agent/protect.c b/agent/protect.c
index a9de732..c257861 100644
--- a/agent/protect.c
+++ b/agent/protect.c
@@ -54,7 +54,7 @@
/* A table containing the information needed to create a protected
private key. */
-static struct {
+static const struct {
const char *algo;
const char *parmlist;
int prot_from, prot_to;
@@ -238,7 +238,7 @@ get_standard_s2k_count_rfc4880 (void)
/* 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
+static gpg_error_t
calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash)
{
const unsigned char *hash_begin, *hash_end;
@@ -381,7 +381,10 @@ do_encryption (const unsigned char *hashbegin, size_t hashlen,
outbuf = gcry_malloc_secure (outlen);
}
if (!outbuf)
- rc = out_of_core ();
+ {
+ rc = out_of_core ();
+ goto leave;
+ }
/* Allocate a buffer for the nonce and the salt. */
if (!rc)
@@ -421,11 +424,13 @@ do_encryption (const unsigned char *hashbegin, size_t hashlen,
}
}
+ if (rc)
+ goto leave;
+
/* Set the IV/nonce. */
- if (!rc)
- {
- rc = gcry_cipher_setiv (hd, iv, use_ocb? 12 : blklen);
- }
+ rc = gcry_cipher_setiv (hd, iv, use_ocb? 12 : blklen);
+ if (rc)
+ goto leave;
if (use_ocb)
{
@@ -436,7 +441,6 @@ do_encryption (const unsigned char *hashbegin, size_t hashlen,
if (!rc)
rc = gcry_cipher_authenticate
(hd, protbegin+protlen, hashlen - (protbegin+protlen - hashbegin));
-
}
else
{
@@ -500,14 +504,11 @@ do_encryption (const unsigned char *hashbegin, size_t hashlen,
}
}
+ if (rc)
+ goto leave;
+
/* Release cipher handle and check for errors. */
gcry_cipher_close (hd);
- if (rc)
- {
- xfree (iv);
- xfree (outbuf);
- return rc;
- }
/* Now allocate the buffer we want to return. This is
@@ -546,6 +547,12 @@ do_encryption (const unsigned char *hashbegin, size_t hashlen,
xfree (iv);
xfree (outbuf);
return 0;
+
+ leave:
+ gcry_cipher_close (hd);
+ xfree (iv);
+ xfree (outbuf);
+ return rc;
}
@@ -721,7 +728,7 @@ agent_protect (const unsigned char *plainkey, const char *passphrase,
/* Do the actual decryption and check the return list for consistency. */
-static int
+static gpg_error_t
do_decryption (const unsigned char *aad_begin, size_t aad_len,
const unsigned char *aadhole_begin, size_t aadhole_len,
const unsigned char *protected, size_t protectedlen,
@@ -731,7 +738,7 @@ do_decryption (const unsigned char *aad_begin, size_t aad_len,
int prot_cipher, int prot_cipher_keylen, int is_ocb,
unsigned char **result)
{
- int rc = 0;
+ int rc;
int blklen;
gcry_cipher_hd_t hd;
unsigned char *outbuf;
@@ -806,7 +813,14 @@ do_decryption (const unsigned char *aad_begin, size_t aad_len,
protected, protectedlen - 16);
}
if (!rc)
- rc = gcry_cipher_checktag (hd, protected + protectedlen - 16, 16);
+ {
+ rc = gcry_cipher_checktag (hd, protected + protectedlen - 16, 16);
+ if (gpg_err_code (rc) == GPG_ERR_CHECKSUM)
+ {
+ /* Return Bad Passphrase instead of checksum error */
+ rc = gpg_error (GPG_ERR_BAD_PASSPHRASE);
+ }
+ }
}
else
{
@@ -826,8 +840,6 @@ do_decryption (const unsigned char *aad_begin, size_t aad_len,
/* Do a quick check on the data structure. */
if (*outbuf != '(' && outbuf[1] != '(')
{
- /* Note that in OCB mode this is actually invalid _encrypted_
- * data and not a bad passphrase. */
xfree (outbuf);
return gpg_error (GPG_ERR_BAD_PASSPHRASE);
}
@@ -851,7 +863,7 @@ do_decryption (const unsigned char *aad_begin, size_t aad_len,
* CUTOFF and CUTLEN will receive the offset and the length of the
* resulting list which should go into the MIC calculation but then be
* removed. */
-static int
+static gpg_error_t
merge_lists (const unsigned char *protectedkey,
size_t replacepos,
const unsigned char *cleartext,
@@ -1004,13 +1016,13 @@ 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 protected_at unless this is NULL. */
-int
+gpg_error_t
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 {
+ static const 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. */
@@ -1284,6 +1296,7 @@ agent_unprotect (ctrl_t ctrl,
return 0;
}
+
/* Check the type of the private key, this is one of the constants:
PRIVATE_KEY_UNKNOWN if we can't figure out the type (this is the
value 0), PRIVATE_KEY_CLEAR for an unprotected private key.
@@ -1542,7 +1555,7 @@ agent_shadow_key (const unsigned char *pubkey,
/* Parse a canonical encoded shadowed key and return a pointer to the
inner list with the shadow_info */
-int
+gpg_error_t
agent_get_shadow_info (const unsigned char *shadowkey,
unsigned char const **shadow_info)
{
diff --git a/artwork/banner/Bungee-Regular.ttf b/artwork/banner/Bungee-Regular.ttf
new file mode 100644
index 0000000..3229ee2
--- /dev/null
+++ b/artwork/banner/Bungee-Regular.ttf
Binary files differ
diff --git a/artwork/banner/Bungee-license.txt b/artwork/banner/Bungee-license.txt
new file mode 100644
index 0000000..17c2929
--- /dev/null
+++ b/artwork/banner/Bungee-license.txt
@@ -0,0 +1,92 @@
+Copyright 2008 The Bungee Project Authors (david@djr.com)
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/artwork/banner/Raleway-ExtraBold.ttf b/artwork/banner/Raleway-ExtraBold.ttf
new file mode 100644
index 0000000..502ff86
--- /dev/null
+++ b/artwork/banner/Raleway-ExtraBold.ttf
Binary files differ
diff --git a/artwork/banner/Raleway-SemiBold.ttf b/artwork/banner/Raleway-SemiBold.ttf
new file mode 100644
index 0000000..ed0a8b9
--- /dev/null
+++ b/artwork/banner/Raleway-SemiBold.ttf
Binary files differ
diff --git a/artwork/banner/Raleway-license.txt b/artwork/banner/Raleway-license.txt
new file mode 100644
index 0000000..f29bd82
--- /dev/null
+++ b/artwork/banner/Raleway-license.txt
@@ -0,0 +1,94 @@
+Copyright (c) 2010, Matt McInerney (matt@pixelspread.com),
+Copyright (c) 2011, Pablo Impallari (www.impallari.com|impallari@gmail.com),
+Copyright (c) 2011, Rodrigo Fuenzalida (www.rfuenzalida.com|hello@rfuenzalida.com), with Reserved Font Name Raleway
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/artwork/banner/banner-full.png b/artwork/banner/banner-full.png
new file mode 100644
index 0000000..37959f4
--- /dev/null
+++ b/artwork/banner/banner-full.png
Binary files differ
diff --git a/artwork/banner/banner-half.png b/artwork/banner/banner-half.png
new file mode 100644
index 0000000..7ef131e
--- /dev/null
+++ b/artwork/banner/banner-half.png
Binary files differ
diff --git a/artwork/banner/banner-rectangle.png b/artwork/banner/banner-rectangle.png
new file mode 100644
index 0000000..1ebd2e2
--- /dev/null
+++ b/artwork/banner/banner-rectangle.png
Binary files differ
diff --git a/artwork/banner/banner-skyscraper.png b/artwork/banner/banner-skyscraper.png
new file mode 100644
index 0000000..e152817
--- /dev/null
+++ b/artwork/banner/banner-skyscraper.png
Binary files differ
diff --git a/artwork/banner/banner.svg b/artwork/banner/banner.svg
new file mode 100644
index 0000000..5f40a97
--- /dev/null
+++ b/artwork/banner/banner.svg
@@ -0,0 +1,509 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="210mm"
+ height="297mm"
+ viewBox="0 0 210 297"
+ version="1.1"
+ id="svg8"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="banner.svg">
+ <defs
+ id="defs2">
+ <style
+ type="text/css"
+ id="style29">
+
+ @font-face { font-family:&quot;CastleT&quot;;src:url(&quot;#FontID0&quot;) format(svg)}
+ .fil1 {fill:white}
+ .fil0 {fill:#0093DD}
+ .fnt1 {font-weight:normal;font-size:40.3513;font-family:'CastleT'}
+ .fnt0 {font-weight:normal;font-size:40.7083;font-family:'CastleT'}
+
+ </style>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.70710678"
+ inkscape:cx="86.193062"
+ inkscape:cy="651.11175"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:snap-grids="true"
+ inkscape:window-width="2554"
+ inkscape:window-height="1388"
+ inkscape:window-x="0"
+ inkscape:window-y="24"
+ inkscape:window-maximized="0"
+ inkscape:lockguides="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-to-guides="true" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <g
+ transform="matrix(0.85495293,0,0,0.85495293,7.5186747,-74.376709)"
+ id="banner-full"
+ inkscape:label="banner-full"
+ inkscape:export-xdpi="151.92"
+ inkscape:export-ydpi="151.92">
+ <rect
+ style="clip-rule:evenodd;fill:#f7f7f7;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+ id="rect5024"
+ width="234.66263"
+ height="31.270552"
+ x="-5.3079839"
+ y="93.239075" />
+ <path
+ id="path4161-3-3"
+ style="font-weight:normal;font-size:40.35129929px;font-family:CastleT;clip-rule:evenodd;fill:#0093dd;fill-opacity:1;fill-rule:evenodd;stroke-width:3.9181118;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+ d="m 66.379648,93.248009 c 69.680832,1.330784 69.771062,10.717721 88.167562,21.954811 14.05202,8.58337 25.56583,9.30681 74.80743,9.30681 V 93.239075 c -18.49181,0.04133 -104.69463,0.0089 -162.974992,0.0089 z"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cscccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="rect5024-5"
+ transform="scale(0.26458333)"
+ d="m -20.0625,352.40039 v 118.1875 h 177.73828 c 4.60768,-4.50064 5.0368,-3.92045 -0.51953,-8.98828 5.21675,-5.21911 5.80832,-4.19833 0,-9.49609 5.21745,-5.21749 5.80794,-4.19864 0,-9.4961 5.2168,-5.2168 5.8055,-4.19653 0,-9.49414 5.21676,-5.21907 5.80831,-4.19833 0,-9.49609 5.21746,-5.21745 5.80794,-4.19867 0,-9.4961 5.21633,-5.21635 5.8062,-4.19845 0,-9.49414 5.21674,-5.21907 5.80833,-4.19836 0,-9.49609 5.21745,-5.21745 5.80795,-4.19867 0,-9.49609 5.21679,-5.21681 5.80551,-4.19655 0,-9.49415 5.21674,-5.21907 5.80833,-4.19833 0,-9.49609 5.21745,-5.21745 5.80794,-4.19667 0,-9.49414 l 4.39453,-4.39453 0.35547,-0.35547 z"
+ style="clip-rule:evenodd;fill:#0093dd;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.90007085;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision" />
+ <text
+ id="text4536"
+ y="102.57482"
+ x="225.84372"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444447px;line-height:125%;font-family:'Libre Baskerville';-inkscape-font-specification:'Libre Baskerville';text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ id="tspan4540"
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:6.3499999px;font-family:Raleway;-inkscape-font-specification:'Raleway Semi-Bold';text-align:end;text-anchor:end;fill:#f7f7f7;fill-opacity:1;stroke-width:0.26458332px"
+ y="102.57482"
+ x="225.9231"
+ sodipodi:role="line">Trusted by <tspan
+ id="tspan4668"
+ style="font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;font-family:Raleway;-inkscape-font-specification:'Raleway Ultra-Bold';letter-spacing:0.079375px;fill:#f7f7f7;fill-opacity:1">activists,</tspan></tspan><tspan
+ id="tspan4612"
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:6.3499999px;font-family:Raleway;-inkscape-font-specification:'Raleway Semi-Bold';text-align:end;text-anchor:end;fill:#f7f7f7;fill-opacity:1;stroke-width:0.26458332px"
+ y="109.94651"
+ x="225.9231"
+ sodipodi:role="line"><tspan
+ id="tspan4672"
+ style="font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;font-family:Raleway;-inkscape-font-specification:'Raleway Ultra-Bold';letter-spacing:0.079375px;fill:#f7f7f7;fill-opacity:1">journalists</tspan> and <tspan
+ id="tspan4674"
+ style="font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;font-family:Raleway;-inkscape-font-specification:'Raleway Ultra-Bold';letter-spacing:0.079375px;fill:#f7f7f7;fill-opacity:1">lawyers</tspan></tspan><tspan
+ id="tspan4631"
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:6.3499999px;font-family:Raleway;-inkscape-font-specification:'Raleway Semi-Bold';text-align:end;text-anchor:end;fill:#f7f7f7;fill-opacity:1;stroke-width:0.26458332px"
+ y="117.31821"
+ x="225.84372"
+ sodipodi:role="line">around the world.</tspan></text>
+ <path
+ id="path4161-6-7-4"
+ style="font-weight:normal;font-size:40.35129929px;font-family:CastleT;clip-rule:evenodd;fill:#0093dd;fill-opacity:1;fill-rule:evenodd;stroke-width:0.52691233;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+ d="m 133.24369,108.8323 v 1.7545 c -1.30117,-0.8859 -2.58849,-1.32885 -3.86195,-1.32885 -1.38422,0 -2.50199,0.47063 -3.35328,1.4119 -0.53292,0.58829 -0.89627,1.23542 -1.09007,1.94137 -0.24223,0.85129 -0.36336,1.79256 -0.36336,2.82381 0,2.12477 0.47755,3.70624 1.43268,4.7444 0.80283,0.87898 1.8583,1.31847 3.16639,1.31847 0.76132,0 1.49148,-0.19725 2.19052,-0.59175 v -5.53342 c 0,-0.25607 -0.0277,-0.48447 -0.0831,-0.68518 h 2.47083 c -0.0554,0.21455 -0.083,0.44295 -0.083,0.68518 v 5.45036 c 0.007,0.31838 0.0519,0.60214 0.13496,0.8513 -1.27349,0.41526 -2.20438,0.68172 -2.79266,0.79938 -0.58139,0.11766 -1.2804,0.17649 -2.09709,0.17649 -1.47419,0 -2.67846,-0.263 -3.6128,-0.789 -1.12122,-0.62982 -1.96214,-1.55379 -2.52275,-2.7719 -0.4914,-1.06585 -0.7371,-2.29434 -0.7371,-3.68548 0,-2.47083 0.76825,-4.37413 2.30473,-5.7099 1.23888,-1.08662 2.88263,-1.62991 4.93128,-1.62991 1.24578,0 2.56771,0.25608 3.96577,0.76823 z m -19.07105,7.51631 v 5.40883 c 0,0.20071 0.0346,0.42911 0.10381,0.68519 h -2.56426 c 0.0623,-0.21456 0.0934,-0.44295 0.0934,-0.68519 v -12.79018 c 0,-0.25608 -0.0311,-0.48794 -0.0934,-0.69555 h 4.53677 c 1.10737,0 2.04518,0.22146 2.81343,0.66441 1.17658,0.69211 1.76487,1.77526 1.76487,3.24945 0,1.63338 -0.71633,2.80996 -2.149,3.52976 -0.83745,0.42219 -1.83755,0.63328 -3.00029,0.63328 z m 0,-1.09007 h 1.26656 c 0.6921,0 1.24925,-0.12458 1.67143,-0.37374 0.40143,-0.24224 0.7198,-0.60214 0.95512,-1.07969 0.23531,-0.47756 0.35297,-1.00702 0.35297,-1.5884 0,-0.89974 -0.24916,-1.60569 -0.74748,-2.11785 -0.49139,-0.51908 -1.16966,-0.77862 -2.0348,-0.77862 h -1.4638 z m -7.52669,7.18409 v -1.51572 c -0.39451,0.53984 -0.77517,0.92743 -1.14198,1.16274 -0.58138,0.36682 -1.31155,0.55023 -2.19053,0.55023 -1.18351,0 -2.09363,-0.33568 -2.73037,-1.00702 -0.52601,-0.55369 -0.789023,-1.35307 -0.789023,-2.39815 v -7.1841 c 0,-0.23532 -0.0277,-0.46025 -0.0831,-0.67481 h 2.335883 c -0.0554,0.1938 -0.0831,0.41873 -0.0831,0.67481 v 6.94532 c 0,0.59521 0.14188,1.06931 0.42564,1.42228 0.37374,0.44987 0.93435,0.67481 1.68183,0.67481 0.7544,0 1.36345,-0.21456 1.82717,-0.64366 0.47063,-0.43603 0.70595,-1.0001 0.70595,-1.69221 v -6.70654 c 0,-0.24224 -0.0277,-0.46718 -0.0831,-0.67481 h 2.33586 c -0.0554,0.17995 -0.0831,0.40489 -0.0831,0.67481 v 9.70683 c 0,0.22148 0.0277,0.44987 0.0831,0.68519 z M 87.834416,111.3758 h 2.21128 v 1.54687 c 0.33222,-0.51909 0.66789,-0.89974 1.00702,-1.14198 0.63674,-0.44295 1.44305,-0.66443 2.41893,-0.66443 1.25963,0 2.21474,0.38412 2.86532,1.15237 0.41527,0.49139 0.6229,1.17658 0.6229,2.05556 v 7.43325 c 0,0.2284 0.0277,0.45679 0.0831,0.68519 h -2.33587 c 0.0554,-0.17303 0.0831,-0.40142 0.0831,-0.68519 v -7.11142 c 0,-0.62982 -0.18341,-1.11776 -0.55023,-1.46381 -0.36682,-0.34606 -0.88936,-0.51909 -1.56762,-0.51909 -0.84438,0 -1.48112,0.23532 -1.91022,0.70596 -0.44988,0.49831 -0.67481,1.13852 -0.67481,1.9206 v 6.46776 c 0,0.24224 0.0277,0.47063 0.0831,0.68519 h -2.33586 c 0.0554,-0.20071 0.0831,-0.42911 0.0831,-0.68519 v -9.70683 c 0,-0.23532 -0.0277,-0.46025 -0.0831,-0.67481 z m -3.05221,-2.5435 v 1.7545 c -1.30116,-0.8859 -2.58849,-1.32885 -3.86197,-1.32885 -1.38421,0 -2.50197,0.47063 -3.35327,1.4119 -0.53292,0.58829 -0.89628,1.23542 -1.09007,1.94137 -0.24224,0.85129 -0.36336,1.79256 -0.36336,2.82381 0,2.12477 0.47756,3.70624 1.43267,4.7444 0.80285,0.87898 1.85832,1.31847 3.1664,1.31847 0.76132,0 1.4915,-0.19725 2.19052,-0.59175 v -5.53342 c 0,-0.25607 -0.0277,-0.48447 -0.0831,-0.68518 h 2.47083 c -0.0554,0.21455 -0.0831,0.44295 -0.0831,0.68518 v 5.45036 c 0.007,0.31838 0.0519,0.60214 0.13496,0.8513 -1.27348,0.41526 -2.20437,0.68172 -2.79266,0.79938 -0.58137,0.11766 -1.2804,0.17649 -2.0971,0.17649 -1.47419,0 -2.67845,-0.263 -3.6128,-0.789 -1.12122,-0.62982 -1.96213,-1.55379 -2.52274,-2.7719 -0.4914,-1.06585 -0.7371,-2.29434 -0.7371,-3.68548 0,-2.47083 0.76825,-4.37413 2.30473,-5.7099 1.23887,-1.08662 2.88263,-1.62991 4.93127,-1.62991 1.2458,0 2.56773,0.25608 3.96579,0.76823 z"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccsccscscsccscccsccscsccsccsscscscsccscsscscccccscssccsscscssccssccccccscssccsssscssccsscccsccscscsccscccsccscsc" />
+ <path
+ id="path4161-3-0-0"
+ style="font-weight:normal;font-size:40.35129929px;font-family:CastleT;clip-rule:evenodd;fill:#0093dd;fill-opacity:1;fill-rule:evenodd;stroke-width:0.51351911;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+ d="m 48.736304,108.39215 1.457727,5.3e-4 9.82e-4,-4.38798 c 0.0011,-4.919043 3.991421,-8.907421 8.91042,-8.906262 4.919156,0.0011 8.907282,3.991423 8.906122,8.910482 l -8.01e-4,4.34463 c -0.02131,0.0147 -0.042,0.029 -0.06265,0.0432 h 1.37e-4 l -0.01323,0.01 -0.0016,8.6e-4 -0.0016,8.4e-4 -0.0016,8.5e-4 -0.007,0.005 -0.0078,0.006 -0.0016,8.5e-4 -0.0089,0.006 -4.06e-4,3.2e-4 -0.0035,0.002 -0.0021,0.002 -0.0039,0.004 -9.82e-4,5e-4 -0.0054,0.004 -5.3e-5,-1e-5 -0.0054,0.004 -0.007,0.005 -0.0035,0.003 -0.003,0.002 -0.0026,0.002 -0.0078,0.006 -0.0078,0.006 -4.09e-4,2.4e-4 -0.0097,0.007 -0.0021,0.002 -0.01247,0.008 -9.82e-4,5e-4 -0.005,0.004 -1.32e-4,1.2e-4 -0.0021,8.7e-4 -0.0158,0.0109 -0.0026,0.002 -0.0035,0.003 -0.0016,8.5e-4 -9.81e-4,8.6e-4 -0.0085,0.006 -9.82e-4,4.9e-4 -2.73e-4,1.4e-4 -5.13e-4,3e-4 -0.0094,0.006 -0.0021,8.6e-4 -0.003,0.002 -0.003,0.002 -0.0021,0.002 -0.005,0.004 -0.0048,0.004 -4.05e-4,1.5e-4 -0.005,0.004 -5.16e-4,3.6e-4 -0.0046,0.003 -0.0016,8.6e-4 -0.0035,0.003 -0.0026,0.002 -0.0026,0.002 -0.003,0.002 -0.0021,8.8e-4 -0.02702,0.0176 -0.006,0.004 -0.0016,8.5e-4 -0.01439,0.009 -9.81e-4,5.2e-4 -0.0162,0.01 -4.08e-4,2.6e-4 -9.82e-4,5e-4 -0.0046,0.003 -2.65e-4,1.4e-4 -0.0048,0.004 -5.18e-4,3.1e-4 -0.0041,0.003 -0.0041,0.003 -5.08e-4,3.6e-4 -0.0021,0.002 -0.007,0.005 -0.0035,0.003 -0.0054,0.004 -0.01603,0.01 -0.01603,0.01 -0.01603,0.009 -0.01603,0.01 -0.03222,0.019 -0.01641,0.009 -0.0162,0.0101 -0.007,0.005 -0.0427,0.0242 -0.017,0.01 -0.017,0.01 -0.017,0.01 -0.02215,0.013 -0.02867,0.0162 -0.017,0.01 -0.06636,0.037 -0.003,0.002 -0.0174,0.01 -0.01739,0.01 -0.0041,0.002 -0.02334,0.0126 -0.05218,0.0289 -0.02474,0.0132 c -0.0253,0.0135 -0.05056,0.027 -0.07614,0.0407 l -0.0065,0.004 -0.01188,0.006 -0.03719,0.0194 -0.01881,0.01 -0.003,0.002 -0.03422,0.018 -1.32e-4,10e-5 -0.01882,0.01 -0.0054,0.003 -0.03265,0.0171 -0.0193,0.01 -0.01781,0.009 c -0.02375,0.0123 -0.04807,0.0248 -0.07275,0.037 l -0.0198,0.0103 c -0.0287,0.0146 -0.05769,0.0294 -0.08704,0.0435 l -2.76e-4,10e-5 c -0.0282,0.0141 -0.0562,0.0279 -0.08481,0.042 l -0.0282,0.0137 c -0.03117,0.0151 -0.06229,0.0303 -0.09396,0.0454 l -1.35e-4,1e-5 c -1.767677,0.84478 -4.604986,1.74327 -9.990968,2.12862 -3.85839,0.27629 -6.197818,1.97394 -7.723915,4.02305 l 0.0018,-6.99281 z m 5.561053,9.3e-4 9.609948,0.002 9.82e-4,-4.38797 c 5.06e-4,-2.6534 -2.150515,-4.805565 -4.803818,-4.80619 -2.653249,-5.03e-4 -4.805505,2.15052 -4.806124,4.80392 z m 12.448361,0.695 c -0.0287,0.0146 -0.05769,0.0288 -0.08704,0.0435 M 63.140469,97.254285 c -1.142209,-0.682894 -2.47763,-1.075943 -3.90475,-1.076279 -3.911889,-6.89e-4 -7.137067,2.945656 -7.57661,6.739914 1.147637,-3.5876 4.509896,-6.185783 8.477757,-6.18484 1.053998,2.51e-4 2.065227,0.184331 3.003603,0.521205 z m 6.32757,12.822295 -0.0029,12.57368 -17.737202,-0.005 c 1.955532,-1.08667 3.412716,-0.97561 5.826185,-0.89871 3.286657,0.10474 6.918637,-1.2713 8.705137,-3.09397 1.786705,-1.82287 -0.161536,-0.43145 -2.183706,0.081 -2.022461,0.51217 -5.935645,0.56584 -8.551197,-0.12233 8.238363,0.11429 11.445249,-2.54995 13.266597,-4.93621 1.821243,-2.38619 -0.787383,-0.41453 -2.477212,0.40782 -1.689732,0.8231 -4.636587,1.41077 -7.876739,0.98095 4.904727,-0.009 8.637197,-2.45915 11.031105,-4.98807 z"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccsssccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccsssccccscscccccccccccc" />
+ <text
+ transform="scale(1.0610964,0.94242144)"
+ id="text4513"
+ y="105.98806"
+ x="1.1023052"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.73796225px;line-height:125%;font-family:Bungee;-inkscape-font-specification:Bungee;letter-spacing:0px;word-spacing:0px;fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:0.28074843px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ id="tspan4539"
+ style="fill:#f7f7f7;fill-opacity:1;stroke-width:0.28074843px"
+ y="105.98806"
+ x="1.1023052"
+ sodipodi:role="line">support</tspan></text>
+ <text
+ transform="scale(1.1472696,0.87163471)"
+ id="text4550"
+ y="121.31692"
+ x="0.9147917"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.28516245px;line-height:125%;font-family:Bungee;-inkscape-font-specification:Bungee;letter-spacing:0px;word-spacing:0px;fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:0.3035484px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ id="tspan4552"
+ style="fill:#f7f7f7;fill-opacity:1;stroke-width:0.3035484px"
+ y="121.31692"
+ x="0.9147917"
+ sodipodi:role="line">online</tspan></text>
+ <text
+ transform="scale(0.79200694,1.2626152)"
+ id="text4558"
+ y="91.832733"
+ x="1.3033004"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.18701935px;line-height:125%;font-family:Bungee;-inkscape-font-specification:Bungee;letter-spacing:0px;word-spacing:0px;fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:0.38279247px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="fill:#f7f7f7;fill-opacity:1;stroke-width:0.38279247px"
+ y="91.832733"
+ x="1.3033004"
+ id="tspan4556"
+ sodipodi:role="line">privacy</tspan></text>
+ <text
+ transform="scale(1.4412105,0.69386117)"
+ id="text4562"
+ y="176.64047"
+ x="0.43311256"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.15168762px;line-height:125%;font-family:Bungee;-inkscape-font-specification:Bungee;letter-spacing:0px;word-spacing:0px;fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:0.38132027px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="fill:#f7f7f7;fill-opacity:1;stroke-width:0.38132027px"
+ y="176.64047"
+ x="0.43311256"
+ id="tspan4560"
+ sodipodi:role="line">now!</tspan></text>
+ </g>
+ <flowRoot
+ xml:space="preserve"
+ id="flowRoot4564"
+ style="fill:black;stroke:none;stroke-opacity:1;stroke-width:1px;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;font-family:Bungee;font-style:normal;font-weight:normal;font-size:24px;line-height:125%;letter-spacing:0px;word-spacing:0px;-inkscape-font-specification:Bungee;font-stretch:normal;font-variant:normal"><flowRegion
+ id="flowRegion4566"><rect
+ id="rect4568"
+ width="218.57143"
+ height="235"
+ x="-63.57143"
+ y="298.94824" /></flowRegion><flowPara
+ id="flowPara4570" /></flowRoot> <flowRoot
+ xml:space="preserve"
+ id="flowRoot4578"
+ style="fill:black;stroke:none;stroke-opacity:1;stroke-width:1px;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;font-family:Bungee;font-style:normal;font-weight:normal;font-size:24px;line-height:125%;letter-spacing:0px;word-spacing:0px;-inkscape-font-specification:Bungee;font-stretch:normal;font-variant:normal"><flowRegion
+ id="flowRegion4580"><rect
+ id="rect4582"
+ width="125"
+ height="135.71428"
+ x="55"
+ y="344.66254" /></flowRegion><flowPara
+ id="flowPara4584" /></flowRoot> <g
+ id="banner-skyscraper"
+ transform="translate(-4.1694048,1.4432554)"
+ inkscape:label="banner-skyscraper"
+ inkscape:export-xdpi="154.58743"
+ inkscape:export-ydpi="154.58743">
+ <rect
+ style="clip-rule:evenodd;fill:#f7f7f7;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.25882909;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+ id="rect5024-7"
+ width="178.27115"
+ height="39.391243"
+ x="64.846138"
+ y="-205.66522"
+ transform="rotate(90)" />
+ <path
+ id="path4161-3-3-0"
+ style="font-weight:normal;font-size:40.35129929px;font-family:CastleT;clip-rule:evenodd;fill:#0093dd;fill-opacity:1;fill-rule:evenodd;stroke-width:3.85950589;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+ d="m 205.65818,147.9287 c -0.62061,10.52613 -11.8767,12.01196 -17.70942,12.97579 -10.19433,1.68457 -21.66753,3.04046 -21.66753,13.85278 0,15.40163 0.022,55.57051 0.022,68.36 h 39.39123 c 0,-15.62641 -0.0363,-78.36208 -0.0363,-95.18857 z"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csscccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="rect5024-5-9"
+ d="m 205.64785,45.947328 h -39.37384 v 40.205519 c 1.49939,1.042286 1.3061,1.139356 2.99442,-0.117521 1.73875,1.180062 1.39867,1.313878 3.1636,0 1.73819,1.18022 1.39876,1.313792 3.1636,0 1.73797,1.180073 1.39805,1.313241 3.16295,0 1.73871,1.180064 1.39866,1.313876 3.16359,0 1.73818,1.180222 1.39879,1.313792 3.1636,0 1.73781,1.179967 1.39871,1.313399 3.16294,0 1.73872,1.180059 1.39868,1.313881 3.1636,0 1.73819,1.18022 1.39878,1.313795 3.1636,0 1.73796,1.180071 1.39806,1.313243 3.16295,0 1.73872,1.180059 1.39866,1.313881 3.1636,0 1.73817,1.18022 1.3981,1.313792 3.16294,0 l 1.46403,0.99407 0.11841,0.08041 z"
+ style="clip-rule:evenodd;fill:#0093dd;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.24708542;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision" />
+ <text
+ id="text4536-3"
+ y="183.16814"
+ x="185.95073"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.82573462px;line-height:125%;font-family:'Libre Baskerville';-inkscape-font-specification:'Libre Baskerville';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:0.22620629px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ id="tspan4540-6"
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:5.42895126px;line-height:150%;font-family:Raleway;-inkscape-font-specification:'Raleway Semi-Bold';text-align:center;letter-spacing:0.02910417px;text-anchor:middle;fill:#f7f7f7;fill-opacity:1;stroke-width:0.22620629px"
+ y="183.16814"
+ x="185.96529"
+ sodipodi:role="line">Trusted by</tspan><tspan
+ id="tspan6438"
+ style="font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;font-size:5.42895126px;line-height:150%;font-family:Raleway;-inkscape-font-specification:'Raleway Ultra-Bold';text-align:center;letter-spacing:0.02910417px;text-anchor:middle;fill:#f7f7f7;fill-opacity:1;stroke-width:0.22620629px"
+ y="191.31157"
+ x="185.96529"
+ sodipodi:role="line">activists,</tspan><tspan
+ id="tspan4612-6"
+ style="font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;font-size:5.42895126px;line-height:150%;font-family:Raleway;-inkscape-font-specification:'Raleway Ultra-Bold';text-align:center;letter-spacing:0.02910417px;text-anchor:middle;fill:#f7f7f7;fill-opacity:1;stroke-width:0.22620629px"
+ y="199.45499"
+ x="185.96529"
+ sodipodi:role="line">journalists</tspan><tspan
+ id="tspan6442"
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:5.42895126px;line-height:150%;font-family:Raleway;-inkscape-font-specification:'Raleway Semi-Bold';text-align:center;letter-spacing:0.02910417px;text-anchor:middle;fill:#f7f7f7;fill-opacity:1;stroke-width:0.22620629px"
+ y="207.59842"
+ x="185.96529"
+ sodipodi:role="line">and <tspan
+ id="tspan4674-6"
+ style="font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;line-height:150%;font-family:Raleway;-inkscape-font-specification:'Raleway Ultra-Bold';text-align:center;letter-spacing:0.02910417px;text-anchor:middle;fill:#f7f7f7;fill-opacity:1;stroke-width:0.22620629px">lawyers</tspan></tspan><tspan
+ id="tspan4631-1"
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:5.42895126px;line-height:150%;font-family:Raleway;-inkscape-font-specification:'Raleway Semi-Bold';text-align:center;letter-spacing:0.02910417px;text-anchor:middle;fill:#f7f7f7;fill-opacity:1;stroke-width:0.22620629px"
+ y="215.74185"
+ x="185.96529"
+ sodipodi:role="line">around</tspan><tspan
+ id="tspan6445"
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:5.42895126px;line-height:150%;font-family:Raleway;-inkscape-font-specification:'Raleway Semi-Bold';text-align:center;letter-spacing:0.02910417px;text-anchor:middle;fill:#f7f7f7;fill-opacity:1;stroke-width:0.22620629px"
+ y="223.88527"
+ x="185.96529"
+ sodipodi:role="line">the world.</tspan></text>
+ <path
+ id="path4161-3-0-0-7"
+ style="font-weight:normal;font-size:40.35129929px;font-family:CastleT;clip-rule:evenodd;fill:#0093dd;fill-opacity:1;fill-rule:evenodd;stroke-width:0.71938753;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+ d="m 171.44805,113.35539 2.04213,7.5e-4 9.1e-4,-6.14709 c 9.1e-4,-6.8911 5.59158,-12.478411 12.4826,-12.476772 6.89123,0.0011 12.47819,5.591562 12.47655,12.482662 l -9.1e-4,6.08638 c -0.0298,0.0206 -0.0588,0.0408 -0.0879,0.0605 h 1.8e-4 l -0.0185,0.0138 -9.1e-4,9.1e-4 -9.1e-4,9.1e-4 -9.1e-4,9.1e-4 -0.009,0.005 -0.0102,0.008 -9.1e-4,9.1e-4 -0.0122,0.008 -5.6e-4,4.4e-4 -0.005,0.004 -0.004,0.004 -0.005,0.005 -9.1e-4,7e-4 -0.008,0.005 -8e-5,-2e-5 -0.008,0.005 -0.009,0.005 -0.005,0.005 -0.005,0.004 -0.004,0.004 -0.0102,0.008 -0.0102,0.008 -5.8e-4,3.4e-4 -0.0138,0.009 -0.004,0.004 -0.0174,0.0102 -9.1e-4,7e-4 -0.008,0.005 -1.8e-4,1.7e-4 -0.004,9.1e-4 -0.0221,0.0153 -0.004,0.004 -0.005,0.005 -9.1e-4,9.1e-4 -9.1e-4,9.1e-4 -0.0122,0.008 -9.1e-4,6.6e-4 -3.8e-4,2.1e-4 -7.2e-4,4.2e-4 -0.0138,0.008 -0.004,9.1e-4 -0.005,0.004 -0.005,0.004 -0.004,0.004 -0.008,0.005 -0.005,0.005 -5.6e-4,2e-4 -0.008,0.005 -7.1e-4,5e-4 -0.005,0.005 -9.1e-4,9.1e-4 -0.005,0.005 -0.004,0.004 -0.004,0.004 -0.005,0.004 -0.004,9.1e-4 -0.0378,0.0247 -0.008,0.005 -9.1e-4,9.1e-4 -0.0201,0.0138 -9.1e-4,7.1e-4 -0.0227,0.0138 -5.6e-4,3.5e-4 -9.1e-4,7.2e-4 -0.005,0.005 -3.7e-4,2.1e-4 -0.005,0.005 -7.1e-4,4.3e-4 -0.005,0.005 -0.005,0.005 -7.1e-4,4.8e-4 -0.004,0.004 -0.009,0.005 -0.005,0.005 -0.008,0.005 -0.0225,0.0138 -0.0225,0.0138 -0.0225,0.0138 -0.0225,0.0138 -0.0452,0.0266 -0.0231,0.0138 -0.0227,0.0138 -0.009,0.005 -0.0599,0.0339 -0.0238,0.0138 -0.0238,0.0138 -0.0238,0.0138 -0.0309,0.0183 -0.0402,0.0227 -0.0238,0.0138 -0.093,0.0517 -0.005,0.004 -0.0244,0.0138 -0.0244,0.0138 -0.005,0.004 -0.0326,0.0175 -0.073,0.0405 -0.0348,0.0186 c -0.0355,0.019 -0.0708,0.0378 -0.10657,0.0572 l -0.009,0.005 -0.0166,0.008 -0.0521,0.0273 -0.0265,0.0138 -0.005,0.004 -0.0479,0.0252 -1.8e-4,1.4e-4 -0.0265,0.0138 -0.008,0.005 -0.0457,0.0238 -0.027,0.0138 -0.0248,0.0138 c -0.0334,0.0171 -0.0674,0.0348 -0.10184,0.052 l -0.0278,0.0138 c -0.0401,0.0205 -0.0808,0.041 -0.12188,0.0608 l -4e-4,1.5e-4 c -0.0396,0.0199 -0.0787,0.0391 -0.11883,0.0588 l -0.0396,0.0192 c -0.0437,0.021 -0.0872,0.0425 -0.13167,0.0635 l -2.1e-4,2e-5 c -2.47631,1.18344 -6.45109,2.44214 -13.9963,2.98198 -5.40522,0.38704 -8.68251,2.76528 -10.82042,5.63589 l 0.004,-9.79622 z m 7.79047,9.1e-4 13.46254,0.004 9.1e-4,-6.14708 c 7e-4,-3.71716 -3.01266,-6.73212 -6.72967,-6.733 -3.71692,-7e-4 -6.73202,3.01266 -6.73288,6.72983 z m 17.43888,0.97362 c -0.0401,0.0205 -0.0808,0.0404 -0.12189,0.0608 m -4.92863,-16.638779 c -1.60013,-0.956663 -3.47093,-1.507275 -5.47017,-1.50775 -5.48016,-0.001 -9.99831,4.126549 -10.61405,9.441909 1.60772,-5.02586 6.3179,-8.665623 11.87647,-8.664311 1.47654,3.5e-4 2.89317,0.258234 4.20775,0.730152 z m 8.86427,17.962719 -0.005,17.61443 -24.848,-0.005 c 2.73949,-1.52228 4.78084,-1.36671 8.16189,-1.25899 4.60425,0.14678 9.69229,-1.78097 12.19499,-4.33434 2.50299,-2.55365 -0.22628,-0.60441 -3.05914,0.1135 -2.83326,0.7175 -8.31524,0.79268 -11.97936,-0.17137 11.5411,0.1601 16.03362,-3.57222 18.58514,-6.91513 2.55138,-3.34282 -1.10304,-0.58072 -3.47031,0.57132 -2.36715,1.15307 -6.49539,1.97633 -11.03451,1.37421 6.87103,-0.0122 12.09983,-3.44503 15.45346,-6.98778 z"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccsssccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccsssccccscscccccccccccc" />
+ <g
+ id="g6319"
+ transform="matrix(0,-1.3075888,1.1220953,0,109.03573,309.26076)">
+ <g
+ id="g7302">
+ <text
+ transform="matrix(0,1.0610964,-0.94242144,0,0,0)"
+ id="text4513-9"
+ y="-206.2484"
+ x="50.535992"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.76064062px;line-height:125%;font-family:Bungee;-inkscape-font-specification:Bungee;letter-spacing:0px;word-spacing:0px;fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:0.2400267px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ id="tspan4539-2"
+ style="fill:#f7f7f7;fill-opacity:1;stroke-width:0.2400267px"
+ y="-206.2484"
+ x="50.535992"
+ sodipodi:role="line">support</tspan></text>
+ <text
+ transform="matrix(0,1.1472696,-0.87163471,0,0,0)"
+ id="text4550-0"
+ y="-217.25165"
+ x="46.650623"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.22847128px;line-height:125%;font-family:Bungee;-inkscape-font-specification:Bungee;letter-spacing:0px;word-spacing:0px;fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:0.25951961px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ id="tspan4552-2"
+ style="fill:#f7f7f7;fill-opacity:1;stroke-width:0.25951961px"
+ y="-217.25165"
+ x="46.650623"
+ sodipodi:role="line">online</tspan></text>
+ <text
+ transform="matrix(0,0.8416577,-1.1881315,0,0,0)"
+ id="text4558-3"
+ y="-152.7243"
+ x="63.572239"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.39112139px;line-height:125%;font-family:Bungee;-inkscape-font-specification:Bungee;letter-spacing:0px;word-spacing:0px;fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:0.30796337px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="fill:#f7f7f7;fill-opacity:1;stroke-width:0.30796337px"
+ y="-152.7243"
+ x="63.572239"
+ id="tspan4556-7"
+ sodipodi:role="line">privacy</tspan></text>
+ <text
+ transform="matrix(0,1.2397549,-0.80661108,0,0,0)"
+ id="text4562-5"
+ y="-216.97253"
+ x="42.877209"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.09567642px;line-height:125%;font-family:Bungee;-inkscape-font-specification:Bungee;letter-spacing:0px;word-spacing:0px;fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:0.37898648px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="fill:#f7f7f7;fill-opacity:1;stroke-width:0.37898648px"
+ y="-216.97253"
+ x="42.877209"
+ id="tspan4560-9"
+ sodipodi:role="line">now!</tspan></text>
+ </g>
+ </g>
+ <path
+ id="path4161-6-7-4-8-2-0"
+ style="font-weight:normal;font-size:40.35129929px;font-family:CastleT;clip-rule:evenodd;fill:#0093dd;fill-opacity:1;fill-rule:evenodd;stroke-width:0.38332757;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+ d="m 198.76626,138.37452 v 1.27639 c -0.94659,-0.64449 -1.88312,-0.96674 -2.80957,-0.96674 -1.00701,0 -1.82019,0.34238 -2.43949,1.02716 -0.38772,0.42798 -0.65204,0.89876 -0.79304,1.41235 -0.1762,0.6193 -0.26434,1.30407 -0.26434,2.05431 0,1.54577 0.34742,2.69627 1.04228,3.45153 0.58407,0.63947 1.35191,0.9592 2.30355,0.9592 0.55386,0 1.08504,-0.14352 1.5936,-0.43051 v -4.02554 c 0,-0.1863 -0.0201,-0.35246 -0.0606,-0.49848 h 1.79753 c -0.0404,0.15609 -0.0604,0.32225 -0.0604,0.49848 v 3.96512 c 0.005,0.23161 0.0378,0.43806 0.0982,0.61931 -0.92646,0.3021 -1.60366,0.49595 -2.03164,0.58154 -0.42297,0.0856 -0.93149,0.1284 -1.52563,0.1284 -1.07246,0 -1.94857,-0.19133 -2.6283,-0.57398 -0.81569,-0.4582 -1.42746,-1.13039 -1.8353,-2.01657 -0.3575,-0.7754 -0.53624,-1.66911 -0.53624,-2.68117 0,-1.79752 0.55891,-3.18218 1.67669,-4.15395 0.90127,-0.79051 2.0971,-1.18574 3.5875,-1.18574 0.90629,0 1.868,0.18629 2.88507,0.55889 z m -13.87415,5.46808 v 3.93492 c 0,0.14602 0.0252,0.31218 0.0757,0.49848 h -1.86549 c 0.0454,-0.15609 0.0678,-0.32224 0.0678,-0.49848 v -9.30484 c 0,-0.18628 -0.0225,-0.35497 -0.0678,-0.506 h 3.30047 c 0.80562,0 1.48787,0.1611 2.04676,0.48335 0.85596,0.50352 1.28394,1.2915 1.28394,2.36397 0,1.18827 -0.52113,2.04424 -1.56338,2.5679 -0.60925,0.30713 -1.33682,0.4607 -2.18271,0.4607 z m 0,-0.79303 h 0.92142 c 0.50351,0 0.90883,-0.0906 1.21597,-0.27187 0.29203,-0.17624 0.52365,-0.43806 0.69484,-0.78548 0.17119,-0.34742 0.25679,-0.73261 0.25679,-1.15556 0,-0.65456 -0.18127,-1.16814 -0.54379,-1.54074 -0.35749,-0.37763 -0.85092,-0.56644 -1.48032,-0.56644 h -1.06491 z m -3.97765,-4.67507 v 1.2764 c -0.9466,-0.64449 -1.88313,-0.96673 -2.80959,-0.96673 -1.007,0 -1.82016,0.34238 -2.43948,1.02716 -0.38771,0.42797 -0.65206,0.89876 -0.79304,1.41233 -0.17623,0.61932 -0.26435,1.30409 -0.26435,2.05431 0,1.54577 0.34743,2.69628 1.04227,3.45155 0.58408,0.63946 1.35192,0.95919 2.30355,0.95919 0.55386,0 1.08505,-0.14351 1.59361,-0.43051 v -4.02555 c 0,-0.18628 -0.21188,-0.49846 -0.0604,-0.49846 h 1.79753 c -0.0404,0.15608 -0.0604,0.32225 -0.0604,0.49846 v 3.96514 c 0.005,0.23161 0.0378,0.43804 0.0982,0.61931 -0.92647,0.3021 -1.60368,0.49595 -2.03167,0.58154 -0.42294,0.0856 -0.93149,0.1284 -1.52563,0.1284 -1.07247,0 -1.94857,-0.19133 -2.62831,-0.57399 -0.81567,-0.4582 -1.42744,-1.13038 -1.83528,-2.01656 -0.35748,-0.7754 -0.53624,-1.66911 -0.53624,-2.68117 0,-1.79752 0.5589,-3.18218 1.67669,-4.15395 0.90126,-0.79051 2.09711,-1.18575 3.5875,-1.18575 0.9063,0 1.868,0.18629 2.88508,0.55888 z"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccsccscscsccscccsccscscccccsscscscsccccsscsccccccscscsccscccsccscscscc" />
+ </g>
+ <g
+ id="banner-rectangle"
+ transform="matrix(1,0,0,1.0020885,-2.1381566,-1.4321032)"
+ inkscape:label="banner-rectangle"
+ inkscape:export-xdpi="240.08"
+ inkscape:export-ydpi="240.08">
+ <rect
+ y="45.848969"
+ x="8.3223944"
+ height="63.342884"
+ width="126.95303"
+ id="rect6630"
+ style="fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:0.23547353" />
+ <path
+ id="path4161-3-3-0-7"
+ style="font-weight:normal;font-size:40.35129929px;font-family:CastleT;clip-rule:evenodd;fill:#0093dd;fill-opacity:1;fill-rule:evenodd;stroke-width:3.55511189;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+ d="M 135.23646,71.239742 C 134.57501,89.651535 83.598873,90.507167 53.139045,91.617016 5.4601474,93.354269 8.4560292,100.61663 8.3223944,109.19185 H 135.23666 c 0.005,-12.946021 -2e-4,-26.23219 -2e-4,-37.952108 z"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csccc" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0"
+ id="rect5024-5-9-3"
+ d="m 8.3223958,45.848972 -1.28e-4,12.04612 c 1.384182,1.04229 1.206001,1.13958 2.7645952,-0.1173 1.605149,1.18006 1.29108,1.31388 2.920399,0 1.604631,1.18022 1.291172,1.3138 2.9204,0 1.604437,1.18008 1.290583,1.31325 2.919873,0 1.605116,1.18007 1.291604,1.31388 2.920923,0 1.604619,1.18023 1.291179,1.3138 2.920399,0 1.604273,1.17997 1.291204,1.3134 2.919873,0 1.605127,1.18006 1.291089,1.31388 2.9204,0 1.60463,1.18022 1.291179,1.3138 2.920396,0 1.604418,1.18008 1.290597,1.31325 2.919876,0 1.417545,1.16336 2.052273,0.69918 2.920923,0 1.405261,1.18035 2.031499,0.71571 2.919873,0 l 0.0068,0.005 c 1.793202,1.36702 1.153997,1.1714 2.757776,-0.123 1.604437,1.18008 1.290586,1.31325 2.919873,0 1.605119,1.18007 1.291604,1.31388 2.920923,0 1.604623,1.18023 1.291183,1.31381 2.9204,0 1.604276,1.17997 1.291204,1.3134 2.919873,0 1.60513,1.18006 1.291091,1.31388 2.920399,0 1.60463,1.18023 1.291183,1.31381 2.9204,0 1.604415,1.18008 1.29112,1.31325 2.920396,0 1.605128,1.18006 1.29107,1.31388 2.9204,0 1.414761,1.1643 2.049258,0.70083 2.919875,0 1.80048,1.37126 1.15678,1.18076 2.76512,-0.11731 1.60463,1.18022 1.291168,1.31381 2.920396,0 1.604437,1.18008 1.290586,1.31325 2.919876,0 1.605116,1.18007 1.291077,1.31388 2.920397,0 1.604619,1.18023 1.291189,1.31381 2.920399,0 1.60428,1.17997 1.29121,1.3134 2.919884,0 1.60512,1.18006 1.29161,1.31388 2.92092,0 1.60463,1.18022 1.29118,1.31381 2.9204,0 1.60442,1.18008 1.29059,1.31325 2.91987,0 1.21609,1.10526 1.931065,0.79808 2.919875,-8e-5 1.35661,1.12354 1.53566,1.11793 2.92043,2.7e-4 1.55378,1.29686 1.52687,1.12494 2.9204,0 1.60444,1.18008 1.29111,1.31325 2.9204,0 1.60512,1.18007 1.29108,1.31388 2.9204,0 1.60462,1.18023 1.29118,1.31381 2.9204,0 1.60427,1.17997 1.2912,1.3134 2.91987,0 1.60513,1.18006 1.29109,1.31388 2.9204,0 1.60463,1.18022 1.2917,1.31381 2.92092,0 1.60442,1.18008 1.2906,1.31325 2.91988,0 1.60512,1.18006 1.29107,1.31388 2.9204,0 1.60463,1.18022 1.29063,1.31381 2.91987,0 1.20739,1.21667 1.53225,1.0003 1.84911,0.95743 l -0.001,-12.65113 c -37.403985,-7e-5 -85.769275,1.1e-4 -126.9530342,0 z"
+ style="clip-rule:evenodd;fill:#0093dd;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.23740317;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision" />
+ <g
+ id="g7292"
+ transform="translate(0.10075098)">
+ <g
+ transform="translate(-0.1602156)"
+ id="g7284">
+ <path
+ id="path4161-6-7-4-5-8"
+ style="font-weight:normal;font-size:40.35129929px;font-family:CastleT;clip-rule:evenodd;fill:#0093dd;fill-opacity:1;fill-rule:evenodd;stroke-width:0.45048526;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+ d="m 89.258137,75.188088 v 1.50002 c -1.11244,-0.75741 -2.21303,-1.13611 -3.30178,-1.13611 -1.18344,0 -2.13908,0.40237 -2.8669,1.20711 -0.45562,0.50296 -0.76626,1.05623 -0.93195,1.65978 -0.2071,0.72781 -0.31066,1.53255 -0.31066,2.41422 0,1.81659 0.40828,3.16866 1.22487,4.056236 0.68638,0.7515 1.58876,1.12723 2.70712,1.12723 0.65089,0 1.27514,-0.16863 1.87279,-0.50591 v -4.730816 c 0,-0.21893 -0.0237,-0.4142 -0.071,-0.5858 h 2.11243 c -0.0474,0.18343 -0.071,0.37871 -0.071,0.5858 v 4.659796 c 0.006,0.27221 0.0444,0.5148 0.11539,0.72782 -1.08878,0.35504 -1.88463,0.58284 -2.38759,0.68344 -0.49706,0.10059 -1.09468,0.15089 -1.79291,0.15089 -1.26036,0 -2.28996,-0.22485 -3.08878,-0.67456 -0.958583,-0.53847 -1.677533,-1.32842 -2.156833,-2.369836 -0.42012,-0.91126 -0.63018,-1.96156 -0.63018,-3.15092 0,-2.11244 0.65681,-3.73967 1.97043,-4.88169 1.059193,-0.92901 2.464523,-1.3935 4.216023,-1.3935 1.06508,0 2.19526,0.21894 3.39053,0.6568 z m -16.304853,6.42609 v 4.624296 c 0,0.1716 0.0296,0.36687 0.0887,0.58581 h -2.19232 c 0.0533,-0.18345 0.0798,-0.3787 0.0798,-0.58581 V 75.303478 c 0,-0.21894 -0.0266,-0.41717 -0.0798,-0.59467 h 3.87873 c 0.94675,0 1.74853,0.18934 2.40535,0.56804 1.00592,0.59172 1.50888,1.51777 1.50888,2.77813 0,1.39646 -0.61243,2.40238 -1.8373,3.01778 -0.71598,0.36095 -1.57101,0.54142 -2.5651,0.54142 z m 0,-0.93196 h 1.08285 c 0.59172,0 1.06805,-0.10651 1.429,-0.31953 0.3432,-0.2071 0.61539,-0.5148 0.81658,-0.92308 0.20118,-0.40829 0.30177,-0.86095 0.30177,-1.35801 0,-0.76923 -0.21301,-1.37279 -0.63905,-1.81066 -0.42012,-0.44379 -1.00001,-0.66568 -1.73966,-0.66568 h -1.25149 z m -6.434959,6.142066 v -1.29588 c -0.33729,0.46154 -0.662736,0.79291 -0.976341,0.9941 -0.497051,0.31361 -1.121312,0.47041 -1.8728,0.47041 -1.011843,0 -1.789954,-0.28698 -2.334337,-0.86096 -0.449715,-0.47338 -0.674579,-1.1568 -0.674579,-2.050286 v -6.14208 c 0,-0.20118 -0.02368,-0.39349 -0.07105,-0.57693 h 1.997069 c -0.04736,0.16569 -0.07105,0.358 -0.07105,0.57693 v 5.93792 c 0,0.50888 0.121301,0.914206 0.363903,1.215986 0.319529,0.38461 0.798824,0.57694 1.437886,0.57694 0.644977,0 1.165685,-0.18345 1.562145,-0.5503 0.402364,-0.37279 0.603554,-0.855046 0.603554,-1.446766 v -5.73378 c 0,-0.2071 -0.0237,-0.39941 -0.071,-0.57693 h 1.997049 c -0.0474,0.15385 -0.071,0.34617 -0.071,0.57693 v 8.298886 c 0,0.18935 0.0237,0.38462 0.071,0.58581 z M 50.435347,77.362658 h 1.890541 v 1.3225 c 0.284033,-0.44379 0.571013,-0.76923 0.860954,-0.97633 0.544383,-0.37871 1.233742,-0.56806 2.068073,-0.56806 1.076923,0 1.893496,0.3284 2.449711,0.98522 0.355039,0.42012 0.532554,1.00592 0.532554,1.75741 v 6.355076 c 0,0.19528 0.02368,0.39053 0.07105,0.58581 h -1.997059 c 0.04736,-0.14794 0.07105,-0.3432 0.07105,-0.58581 v -6.079926 c 0,-0.53847 -0.156806,-0.95563 -0.470419,-1.25149 -0.313616,-0.29587 -0.760362,-0.4438 -1.340242,-0.4438 -0.721905,0 -1.266287,0.20119 -1.633148,0.60357 -0.384628,0.42603 -0.576932,0.97338 -0.576932,1.64202 v 5.529626 c 0,0.20711 0.02368,0.40236 0.07105,0.58581 h -1.997051 c 0.04736,-0.1716 0.07105,-0.36688 0.07105,-0.58581 v -8.298886 c 0,-0.20118 -0.02368,-0.39349 -0.07105,-0.57693 z m -2.609495,-2.17457 v 1.50002 c -1.11243,-0.75741 -2.213039,-1.13611 -3.301802,-1.13611 -1.183436,0 -2.139068,0.40237 -2.866889,1.20711 -0.455622,0.50296 -0.766278,1.05623 -0.931959,1.65978 -0.207104,0.72781 -0.310656,1.53255 -0.310656,2.41422 0,1.81659 0.408292,3.16866 1.224866,4.056236 0.686399,0.7515 1.588775,1.12723 2.707124,1.12723 0.650891,0 1.275162,-0.16863 1.87279,-0.50591 v -4.730816 c 0,-0.21893 -0.02368,-0.4142 -0.07105,-0.5858 h 2.112444 c -0.04736,0.18343 -0.07105,0.37871 -0.07105,0.5858 v 4.659796 c 0.006,0.27221 0.04437,0.5148 0.115385,0.72782 -1.088766,0.35504 -1.884633,0.58284 -2.387595,0.68344 -0.497044,0.10059 -1.094679,0.15089 -1.79292,0.15089 -1.260364,0 -2.289949,-0.22485 -3.088775,-0.67456 -0.95859,-0.53847 -1.677529,-1.32842 -2.156824,-2.369836 -0.420124,-0.91126 -0.630186,-1.96156 -0.630186,-3.15092 0,-2.11244 0.656818,-3.73967 1.970436,-4.88169 1.059176,-0.92901 2.464514,-1.3935 4.216004,-1.3935 1.065102,0 2.195288,0.21894 3.390564,0.6568 z"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccsccscscsccscccsccscsccsccsscscscsccscsscscccccscssccsscscssccssccccccscssccsssscssccsscccsccscscsccscccsccscsc" />
+ <path
+ id="path4161-3-0-0-4-4"
+ style="font-weight:normal;font-size:40.35129929px;font-family:CastleT;clip-rule:evenodd;fill:#0093dd;fill-opacity:1;fill-rule:evenodd;stroke-width:0.47097108;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+ d="m 16.340263,73.925048 1.336947,4.8e-4 9.39e-4,-4.02441 c 10e-4,-4.51146 3.66071,-8.16938 8.172142,-8.16832 4.511576,10e-4 8.169263,3.66071 8.168199,8.1722 l -7.41e-4,3.98465 c -0.01954,0.0135 -0.03852,0.0267 -0.05746,0.0396 h 1.25e-4 l -0.01213,0.009 -0.0015,7.9e-4 -0.0015,7.7e-4 -0.0015,7.7e-4 -0.0064,0.004 -0.0071,0.005 -0.0015,7.7e-4 -0.0082,0.005 -3.7e-4,2.9e-4 -0.0032,0.002 -0.0019,0.002 -0.0036,0.003 -9.53e-4,4.5e-4 -0.005,0.003 -4.9e-5,-1e-5 -0.005,0.003 -0.0064,0.004 -0.0032,0.003 -0.0028,0.002 -0.0023,0.002 -0.0071,0.005 -0.0071,0.005 -3.7e-4,2.2e-4 -0.0089,0.006 -0.0019,0.002 -0.01144,0.007 -9.53e-4,4.5e-4 -0.0046,0.003 -1.21e-4,1.1e-4 -0.0019,7.9e-4 -0.01449,0.01 -0.0023,0.002 -0.0032,0.003 -0.0015,8e-4 -9.52e-4,7.9e-4 -0.0079,0.005 -9.52e-4,4.3e-4 -2.51e-4,1.3e-4 -4.77e-4,2.7e-4 -0.0086,0.005 -0.0019,7.9e-4 -0.0028,0.002 -0.0028,0.002 -0.0019,0.002 -0.0046,0.003 -0.0044,0.003 -3.71e-4,1.4e-4 -0.0046,0.003 -4.76e-4,3.1e-4 -0.0043,0.003 -0.0015,7.7e-4 -0.0032,0.003 -0.0023,0.002 -0.0023,0.002 -0.0028,0.002 -0.0019,8e-4 -0.02478,0.0161 -0.0055,0.003 -0.0015,7.6e-4 -0.0132,0.008 -9.52e-4,4.8e-4 -0.01486,0.009 -3.71e-4,2.4e-4 -9.52e-4,4.5e-4 -0.0043,0.003 -2.43e-4,1.4e-4 -0.0044,0.003 -4.76e-4,2.9e-4 -0.0038,0.003 -0.0038,0.003 -4.76e-4,3.1e-4 -0.0019,0.002 -0.0064,0.004 -0.0032,0.003 -0.005,0.003 -0.0147,0.008 -0.0147,0.008 -0.0147,0.008 -0.0147,0.008 -0.02956,0.0174 -0.01506,0.008 -0.01486,0.009 -0.0064,0.004 -0.03917,0.0222 -0.01559,0.009 -0.01559,0.009 -0.01559,0.009 -0.02031,0.012 -0.02629,0.0149 -0.01559,0.009 -0.06086,0.0339 -0.0028,0.002 -0.01596,0.009 -0.01595,0.009 -0.0038,0.002 -0.02141,0.0115 -0.04785,0.0265 -0.02269,0.0121 c -0.0232,0.0124 -0.04637,0.0248 -0.06983,0.0374 l -0.006,0.003 -0.01089,0.005 -0.03411,0.0178 -0.01724,0.009 -0.0028,0.002 -0.03139,0.0165 -1.21e-4,1e-4 -0.01725,0.009 -0.005,0.003 -0.02995,0.0157 -0.0177,0.009 -0.01634,0.008 c -0.02178,0.0112 -0.04408,0.0227 -0.06672,0.0339 l -0.01816,0.009 c -0.02632,0.0134 -0.05291,0.0269 -0.07983,0.0398 l -2.53e-4,9e-5 c -0.02586,0.013 -0.05155,0.0256 -0.07778,0.0386 l -0.02586,0.0126 c -0.02859,0.0139 -0.05713,0.0278 -0.08617,0.0416 l -1.25e-4,1e-5 c -1.621129,0.77487 -4.223351,1.59892 -9.163074,1.95234 -3.5387,0.25339 -5.684293,1.81039 -7.083944,3.68972 l 0.0016,-6.41342 z m 5.100289,8.5e-4 8.813708,0.002 9.52e-4,-4.0244 c 4.77e-4,-2.43356 -1.972332,-4.4074 -4.405793,-4.40797 -2.433413,-4.5e-4 -4.407342,1.97233 -4.40791,4.40589 z m 11.416942,0.63741 c -0.02632,0.0134 -0.05291,0.0264 -0.07983,0.0398 m -3.226703,-10.89309 c -1.04757,-0.62631 -2.272344,-0.98679 -3.581219,-0.9871 -3.587766,-6.3e-4 -6.545721,2.70159 -6.948845,6.18147 1.052549,-3.29034 4.136226,-5.67325 7.775327,-5.67239 0.966668,2.3e-4 1.894112,0.16906 2.754737,0.47802 z m 5.803295,11.7599 -0.0027,11.531876 -16.267572,-0.004 c 1.793504,-0.99663 3.129952,-0.89477 5.343452,-0.82425 3.014338,0.0961 6.345387,-1.16596 7.983866,-2.837606 1.638666,-1.67184 -0.148152,-0.3957 -2.002773,0.0743 -1.854889,0.46973 -5.443843,0.518956 -7.842682,-0.11219 7.555768,0.10481 10.496945,-2.33868 12.167383,-4.52722 1.670343,-2.1885 -0.722143,-0.38019 -2.271959,0.37402 -1.549729,0.75491 -4.252421,1.29388 -7.224107,0.89968 4.498342,-0.008 7.921556,-2.2554 10.117114,-4.57479 z"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccsssccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccsssccccscscccccccccccc" />
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.58728409px;line-height:125%;font-family:Bungee;-inkscape-font-specification:Bungee;letter-spacing:0px;word-spacing:0px;fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:0.27447018px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="17.098032"
+ y="50.515152"
+ id="text4513-9-2"
+ transform="scale(0.92793861,1.0776575)"><tspan
+ sodipodi:role="line"
+ x="17.098032"
+ y="50.515152"
+ style="fill:#f7f7f7;fill-opacity:1;stroke-width:0.27447018px"
+ id="tspan4539-2-0">support online <tspan
+ style="letter-spacing:0.5291667px"
+ id="tspan6835">privacy</tspan> now!</tspan></text>
+ </g>
+ <text
+ id="text4536-5-9"
+ y="99.151093"
+ x="131.25352"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.82573462px;line-height:125%;font-family:'Libre Baskerville';-inkscape-font-specification:'Libre Baskerville';text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:0.2262063px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ id="tspan4612-7-4"
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:5.42895126px;font-family:Raleway;-inkscape-font-specification:'Raleway Semi-Bold';text-align:end;text-anchor:end;fill:#f7f7f7;fill-opacity:1;stroke-width:0.2262063px"
+ y="99.151093"
+ x="131.32138"
+ sodipodi:role="line">Trusted by <tspan
+ id="tspan4668-3-0"
+ style="font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;font-family:Raleway;-inkscape-font-specification:'Raleway Ultra-Bold';letter-spacing:0.0678619px;fill:#f7f7f7;fill-opacity:1;stroke-width:0.2262063px">activists, journalists</tspan></tspan><tspan
+ id="tspan4631-2-1"
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:5.42895126px;font-family:Raleway;-inkscape-font-specification:'Raleway Semi-Bold';text-align:end;text-anchor:end;fill:#f7f7f7;fill-opacity:1;stroke-width:0.2262063px"
+ y="105.45354"
+ x="131.25352"
+ sodipodi:role="line">and <tspan
+ id="tspan4674-5-7"
+ style="font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;font-family:Raleway;-inkscape-font-specification:'Raleway Ultra-Bold';letter-spacing:0.0678619px;fill:#f7f7f7;fill-opacity:1;stroke-width:0.2262063px">lawyers </tspan>around the world.</tspan></text>
+ </g>
+ <g
+ id="banner-half"
+ transform="matrix(1.0020885,0,0,1,0.79361147,-4.0090429)"
+ inkscape:label="banner-half"
+ inkscape:export-xdpi="240.08"
+ inkscape:export-ydpi="240.08">
+ <rect
+ transform="rotate(90)"
+ y="-131.89685"
+ x="121.80496"
+ height="63.342884"
+ width="126.95303"
+ id="rect6630-6-3"
+ style="fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:0.23547353" />
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0"
+ id="rect6630-6"
+ d="m 68.553954,121.80496 v 22.8702 c 1.384183,1.04229 1.206095,1.13957 2.764689,-0.11731 1.60515,1.18006 1.290915,1.31388 2.920235,0 1.604632,1.18022 1.291008,1.3138 2.920236,0 1.604436,1.18008 1.290428,1.31325 2.919719,0 1.605116,1.18007 1.29195,1.31388 2.921267,0 1.604619,1.18023 1.291016,1.3138 2.920236,0 1.604274,1.17997 1.29105,1.3134 2.919719,0 1.605126,1.18006 1.291439,1.31388 2.920751,0 1.604629,1.18022 1.291019,1.3138 2.920235,0 1.604418,1.18008 1.290439,1.31325 2.91972,0 1.417545,1.16336 2.052616,0.69918 2.921269,0 1.40526,1.18035 2.03135,0.71571 2.91972,0 l 0.007,0.005 c 1.7932,1.36702 1.15368,1.17141 2.75746,-0.12299 1.60442,1.18008 1.29043,1.31325 2.91971,0 1.60512,1.18007 1.29195,1.31388 2.92127,0 1.60463,1.18023 1.29103,1.31381 2.92024,0 1.60428,1.17997 1.29105,1.3134 2.91972,0 1.60513,1.18006 1.29144,1.31388 2.92075,0 1.60463,1.18023 1.29101,1.31381 2.92023,0 1.60441,1.18008 1.29097,1.31325 2.92024,0 1.60513,1.18006 1.29142,1.31388 2.92075,0 1.33964,1.26661 1.68126,1.18115 2.32751,0.43718 V 121.80496 H 68.554472 Z"
+ style="fill:#0093dd;fill-opacity:1;stroke:none;stroke-width:0.23547353" />
+ <path
+ id="path4161-3-3-0-7-7"
+ style="font-weight:normal;font-size:40.35129929px;font-family:CastleT;clip-rule:evenodd;fill:#0093dd;fill-opacity:1;fill-rule:evenodd;stroke-width:3.11140203;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+ d="m 99.03702,215.36119 c -32.475299,3.02027 -30.346882,6.26778 -30.48305,33.39681 h 63.34288 c 0,-6.70248 -0.003,-39.35622 -0.003,-56.68626 -0.60224,19.43583 -7.31863,20.91436 -32.85665,23.28945 z"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccsc" />
+ <path
+ id="path4161-6-7-4-5-8-3"
+ style="font-weight:normal;font-size:40.35129929px;font-family:CastleT;clip-rule:evenodd;fill:#0093dd;fill-opacity:1;fill-rule:evenodd;stroke-width:0.45048526;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+ d="m 125.4904,193.31996 v 1.50002 c -1.11244,-0.75741 -2.21303,-1.13611 -3.30178,-1.13611 -1.18344,0 -2.13908,0.40237 -2.8669,1.20711 -0.45562,0.50296 -0.76626,1.05623 -0.93195,1.65978 -0.2071,0.72781 -0.31066,1.53255 -0.31066,2.41422 0,1.81659 0.40828,3.16866 1.22487,4.05623 0.68638,0.7515 1.58876,1.12723 2.70712,1.12723 0.65089,0 1.27514,-0.16863 1.87279,-0.50591 v -4.73081 c 0,-0.21893 -0.0237,-0.4142 -0.071,-0.5858 h 2.11243 c -0.0474,0.18343 -0.071,0.37871 -0.071,0.5858 v 4.65979 c 0.006,0.27221 0.0444,0.5148 0.11539,0.72782 -1.08878,0.35504 -1.88463,0.58284 -2.38759,0.68344 -0.49706,0.10059 -1.09468,0.15089 -1.79291,0.15089 -1.26036,0 -2.28996,-0.22485 -3.08878,-0.67456 -0.95858,-0.53847 -1.67753,-1.32842 -2.15683,-2.36983 -0.42012,-0.91126 -0.63018,-1.96156 -0.63018,-3.15092 0,-2.11244 0.65681,-3.73967 1.97043,-4.88169 1.05919,-0.92901 2.46452,-1.3935 4.21602,-1.3935 1.06508,0 2.19526,0.21894 3.39053,0.6568 z m -16.30485,6.42609 v 4.62429 c 0,0.1716 0.0296,0.36687 0.0887,0.58581 h -2.19232 c 0.0533,-0.18345 0.0798,-0.3787 0.0798,-0.58581 v -10.93499 c 0,-0.21894 -0.0266,-0.41717 -0.0798,-0.59467 h 3.87873 c 0.94675,0 1.74853,0.18934 2.40535,0.56804 1.00592,0.59172 1.50888,1.51777 1.50888,2.77813 0,1.39646 -0.61243,2.40238 -1.8373,3.01778 -0.71598,0.36095 -1.57101,0.54142 -2.5651,0.54142 z m 0,-0.93196 h 1.08285 c 0.59172,0 1.06805,-0.10651 1.429,-0.31953 0.3432,-0.2071 0.61539,-0.5148 0.81658,-0.92308 0.20118,-0.40829 0.30177,-0.86095 0.30177,-1.35801 0,-0.76923 -0.21301,-1.37279 -0.63905,-1.81066 -0.42012,-0.44379 -1.00001,-0.66568 -1.73966,-0.66568 h -1.25149 z m -6.43496,6.14206 v -1.29588 c -0.33729,0.46154 -0.66274,0.79291 -0.97634,0.9941 -0.49706,0.31361 -1.12131,0.47041 -1.872804,0.47041 -1.011852,0 -1.789962,-0.28698 -2.334342,-0.86096 -0.44971,-0.47338 -0.67458,-1.1568 -0.67458,-2.05028 v -6.14208 c 0,-0.20118 -0.0237,-0.39349 -0.071,-0.57693 h 1.99707 c -0.0474,0.16569 -0.071,0.358 -0.071,0.57693 v 5.93792 c 0,0.50888 0.1213,0.9142 0.3639,1.21598 0.31953,0.38461 0.798832,0.57694 1.437896,0.57694 0.64498,0 1.16568,-0.18345 1.56214,-0.5503 0.40237,-0.37279 0.60356,-0.85504 0.60356,-1.44676 v -5.73378 c 0,-0.2071 -0.0237,-0.39941 -0.071,-0.57693 h 1.99705 c -0.0474,0.15385 -0.071,0.34617 -0.071,0.57693 v 8.29888 c 0,0.18935 0.0237,0.38462 0.071,0.58581 z m -16.082986,-9.46162 h 1.89054 v 1.3225 c 0.28403,-0.44379 0.57101,-0.76923 0.86096,-0.97633 0.54438,-0.37871 1.23374,-0.56806 2.06807,-0.56806 1.07692,0 1.89349,0.3284 2.44971,0.98522 0.35504,0.42012 0.53255,1.00592 0.53255,1.75741 v 6.35507 c 0,0.19528 0.0237,0.39053 0.071,0.58581 h -1.99706 c 0.0474,-0.14794 0.071,-0.3432 0.071,-0.58581 v -6.07992 c 0,-0.53847 -0.1568,-0.95563 -0.47041,-1.25149 -0.31362,-0.29587 -0.76037,-0.4438 -1.34025,-0.4438 -0.7219,0 -1.26628,0.20119 -1.63314,0.60357 -0.38463,0.42603 -0.57694,0.97338 -0.57694,1.64202 v 5.52962 c 0,0.20711 0.0237,0.40236 0.071,0.58581 h -1.99705 c 0.0474,-0.1716 0.071,-0.36688 0.071,-0.58581 v -8.29888 c 0,-0.20118 -0.0237,-0.39349 -0.071,-0.57693 z m -2.60949,-2.17457 v 1.50002 c -1.11243,-0.75741 -2.21304,-1.13611 -3.301807,-1.13611 -1.183436,0 -2.139068,0.40237 -2.866889,1.20711 -0.455622,0.50296 -0.766278,1.05623 -0.931959,1.65978 -0.207104,0.72781 -0.310656,1.53255 -0.310656,2.41422 0,1.81659 0.408292,3.16866 1.224866,4.05623 0.686399,0.7515 1.588775,1.12723 2.707124,1.12723 0.650891,0 1.275161,-0.16863 1.872791,-0.50591 v -4.73081 c 0,-0.21893 -0.0237,-0.4142 -0.071,-0.5858 h 2.11244 c -0.0474,0.18343 -0.071,0.37871 -0.071,0.5858 v 4.65979 c 0.006,0.27221 0.0444,0.5148 0.11539,0.72782 -1.08877,0.35504 -1.88463,0.58284 -2.3876,0.68344 -0.49704,0.10059 -1.094676,0.15089 -1.792917,0.15089 -1.260364,0 -2.289949,-0.22485 -3.088775,-0.67456 -0.95859,-0.53847 -1.677529,-1.32842 -2.156824,-2.36983 -0.420124,-0.91126 -0.630186,-1.96156 -0.630186,-3.15092 0,-2.11244 0.656818,-3.73967 1.970436,-4.88169 1.059176,-0.92901 2.464514,-1.3935 4.216004,-1.3935 1.065102,0 2.195292,0.21894 3.390562,0.6568 z"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccsccscscsccscccsccscsccsccsscscscsccscsscscccccscssccsscscssccssccccccscssccsssscssccsscccsccscscsccscccsccscsc" />
+ <text
+ transform="scale(0.92793861,1.0776575)"
+ id="text4513-9-2-6"
+ y="122.11356"
+ x="108.00305"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.58728409px;line-height:125%;font-family:Bungee;-inkscape-font-specification:Bungee;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:0.27447018px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ id="tspan7238"
+ style="text-align:center;text-anchor:middle;fill:#f7f7f7;fill-opacity:1;stroke-width:0.27447018px"
+ y="122.11356"
+ x="108.00305"
+ sodipodi:role="line">support online<tspan
+ id="tspan6835-9"
+ style="text-align:center;letter-spacing:0.5291667px;text-anchor:middle"></tspan></tspan><tspan
+ id="tspan7243"
+ style="text-align:center;text-anchor:middle;fill:#f7f7f7;fill-opacity:1;stroke-width:0.27447018px"
+ y="130.34767"
+ x="108.00305"
+ sodipodi:role="line"><tspan
+ id="tspan7245"
+ style="text-align:center;letter-spacing:0.5291667px;text-anchor:middle">privacy</tspan> now!</tspan></text>
+ <text
+ id="text4536-5-9-4"
+ y="226.28905"
+ x="100.32907"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.82573462px;line-height:125%;font-family:'Libre Baskerville';-inkscape-font-specification:'Libre Baskerville';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:0.2262063px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ id="tspan4612-7-4-8"
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:5.42895126px;font-family:Raleway;-inkscape-font-specification:'Raleway Semi-Bold';text-align:center;text-anchor:middle;fill:#f7f7f7;fill-opacity:1;stroke-width:0.2262063px"
+ y="226.28905"
+ x="100.363"
+ sodipodi:role="line">Trusted by <tspan
+ id="tspan4668-3-0-1"
+ style="font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;font-family:Raleway;-inkscape-font-specification:'Raleway Ultra-Bold';text-align:center;letter-spacing:0.0678619px;text-anchor:middle;fill:#f7f7f7;fill-opacity:1;stroke-width:0.2262063px">activists,</tspan></tspan><tspan
+ id="tspan4631-2-1-2"
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:5.42895126px;font-family:Raleway;-inkscape-font-specification:'Raleway Semi-Bold';text-align:center;text-anchor:middle;fill:#f7f7f7;fill-opacity:1;stroke-width:0.2262063px"
+ y="232.59149"
+ x="100.32907"
+ sodipodi:role="line"><tspan
+ id="tspan7264"
+ style="font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;font-family:Raleway;-inkscape-font-specification:'Raleway Ultra-Bold';text-align:center;letter-spacing:0.0678619px;text-anchor:middle;fill:#f7f7f7;fill-opacity:1;stroke-width:0.2262063px">journalists </tspan>and</tspan><tspan
+ id="tspan7270"
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:5.42895126px;font-family:Raleway;-inkscape-font-specification:'Raleway Semi-Bold';text-align:center;text-anchor:middle;fill:#f7f7f7;fill-opacity:1;stroke-width:0.2262063px"
+ y="238.89395"
+ x="100.32907"
+ sodipodi:role="line"><tspan
+ id="tspan7274"
+ style="font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;font-family:Raleway;-inkscape-font-specification:'Raleway Ultra-Bold';text-align:center;letter-spacing:0.0678619px;text-anchor:middle;fill:#f7f7f7;fill-opacity:1;stroke-width:0.2262063px">lawyers </tspan>around</tspan><tspan
+ id="tspan7280"
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:5.42895126px;font-family:Raleway;-inkscape-font-specification:'Raleway Semi-Bold';text-align:center;text-anchor:middle;fill:#f7f7f7;fill-opacity:1;stroke-width:0.2262063px"
+ y="245.1964"
+ x="100.32907"
+ sodipodi:role="line">the world.</tspan></text>
+ <path
+ sodipodi:nodetypes="ccsssccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccsssccccscscccccccccccc"
+ inkscape:connector-curvature="0"
+ d="m 85.703861,168.10594 2.04213,7.4e-4 9.1e-4,-6.14709 c 9.1e-4,-6.89109 5.59158,-12.47841 12.482609,-12.47677 6.89122,0.001 12.47818,5.59157 12.47654,12.48267 l -8e-4,6.08638 c -0.0298,0.0206 -0.0588,0.0408 -0.0879,0.0605 h 1.8e-4 l -0.0185,0.0138 -7.9e-4,9e-4 -8e-4,9e-4 -7.9e-4,8.9e-4 -0.009,0.005 -0.0102,0.008 -7.9e-4,9e-4 -0.0122,0.008 -5.3e-4,4.5e-4 -0.005,0.004 -0.004,0.004 -0.005,0.005 -7.9e-4,6.9e-4 -0.008,0.005 -8e-5,-2e-5 -0.008,0.005 -0.009,0.005 -0.005,0.005 -0.005,0.004 -0.004,0.004 -0.0102,0.008 -0.0102,0.008 -5.3e-4,3.5e-4 -0.0138,0.009 -0.004,0.004 -0.0174,0.0102 -7.9e-4,6.8e-4 -0.008,0.005 -1.8e-4,1.7e-4 -0.004,9e-4 -0.0221,0.0153 -0.004,0.004 -0.005,0.005 -7.9e-4,9e-4 -8e-4,9e-4 -0.0122,0.008 -7.9e-4,6.6e-4 -2.7e-4,2.1e-4 -7.9e-4,4.3e-4 -0.0138,0.008 -0.004,9e-4 -0.005,0.004 -0.005,0.004 -0.004,0.004 -0.008,0.005 -0.005,0.005 -5.3e-4,2e-4 -0.008,0.005 -7.9e-4,5e-4 -0.005,0.005 -8e-4,9e-4 -0.005,0.005 -0.004,0.004 -0.004,0.004 -0.005,0.004 -0.004,9e-4 -0.0378,0.0247 -0.008,0.005 -7.9e-4,9e-4 -0.0201,0.0138 -7.9e-4,7.2e-4 -0.0227,0.0138 -5.3e-4,3.4e-4 -8e-4,7.1e-4 -0.005,0.005 -2.6e-4,2.1e-4 -0.005,0.005 -8e-4,4.3e-4 -0.005,0.005 -0.005,0.005 -7.9e-4,4.7e-4 -0.004,0.004 -0.009,0.005 -0.005,0.005 -0.008,0.005 -0.0225,0.0138 -0.0225,0.0138 -0.0225,0.0138 -0.0225,0.0138 -0.0452,0.0266 -0.0231,0.0138 -0.0227,0.0138 -0.009,0.005 -0.0599,0.0339 -0.0238,0.0138 -0.0238,0.0138 -0.0238,0.0138 -0.0309,0.0183 -0.0402,0.0227 -0.0238,0.0138 -0.093,0.0517 -0.005,0.004 -0.0244,0.0138 -0.0244,0.0138 -0.005,0.004 -0.0326,0.0175 -0.073,0.0405 -0.0348,0.0186 c -0.0355,0.019 -0.0708,0.0378 -0.10657,0.0572 l -0.009,0.005 -0.0166,0.008 -0.0521,0.0273 -0.0265,0.0138 -0.005,0.004 -0.0479,0.0252 -1.8e-4,1.4e-4 -0.0265,0.0138 -0.008,0.005 -0.0457,0.0238 -0.027,0.0138 -0.0248,0.0138 c -0.0334,0.0171 -0.0674,0.0348 -0.10184,0.052 l -0.0278,0.0138 c -0.0401,0.0205 -0.0808,0.041 -0.12188,0.0608 l -4e-4,1.5e-4 c -0.0396,0.0199 -0.0787,0.0391 -0.11883,0.0588 l -0.0396,0.0192 c -0.0437,0.021 -0.0872,0.0425 -0.13167,0.0635 l -2.1e-4,2e-5 c -2.47803,1.18354 -6.45281,2.44224 -13.998026,2.98208 -5.40522,0.38704 -8.68251,2.76528 -10.82042,5.63589 l 0.004,-9.79622 z m 7.79047,8.9e-4 13.462539,0.004 9e-4,-6.14708 c 7.1e-4,-3.71714 -3.01265,-6.7321 -6.72965,-6.73298 -3.716929,-7e-4 -6.732029,3.01266 -6.732889,6.72982 z m 17.438879,0.97362 c -0.0401,0.0205 -0.0808,0.0404 -0.12189,0.0608 m -4.92863,-16.63876 c -1.60013,-0.95667 -3.47093,-1.50728 -5.47016,-1.50775 -5.480169,-0.001 -9.998319,4.12655 -10.614059,9.4419 1.60772,-5.02585 6.3179,-8.66562 11.876479,-8.66431 1.47654,3.5e-4 2.89316,0.25824 4.20774,0.73016 z m 8.86427,17.96272 -0.005,17.61443 -24.848008,-0.005 c 2.73949,-1.52228 4.78084,-1.36672 8.16189,-1.259 4.604248,0.14678 9.692298,-1.78096 12.194988,-4.33434 2.50299,-2.55365 -0.22628,-0.6044 -3.05914,0.1135 -2.83326,0.7175 -8.315238,0.79269 -11.979358,-0.17137 11.541098,0.16011 16.033618,-3.57221 18.585138,-6.91512 2.55137,-3.34283 -1.10304,-0.58072 -3.47031,0.57132 -2.36715,1.15307 -6.49539,1.97632 -11.034505,1.3742 6.871025,-0.0122 12.099825,-3.44502 15.453445,-6.98777 z"
+ style="font-weight:normal;font-size:40.35129929px;font-family:CastleT;clip-rule:evenodd;fill:#0093dd;fill-opacity:1;fill-rule:evenodd;stroke-width:0.71938753;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+ id="path4161-3-0-0-7-9" />
+ </g>
+ </g>
+</svg>
diff --git a/build-aux/Vagrantfile b/build-aux/Vagrantfile
new file mode 100644
index 0000000..e4252aa
--- /dev/null
+++ b/build-aux/Vagrantfile
@@ -0,0 +1,36 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+# This Vagrantfile installs all build dependencies for speedo and runs it to compile all of gnupg.
+
+$script = <<SCRIPT
+echo I am provisioning...
+export DEBIAN_FRONTEND noninteractive
+apt-get update -q -q
+apt-get install --yes rsync build-essential git gpg automake autoconf gettext libtool
+apt-get install --yes libz-dev libbz2-dev libldap2-dev libsqlite3-dev libgnutls28-dev libcurl4-gnutls-dev libreadline-dev librsvg2-bin libusb-1.0-0-dev
+apt-get install --yes texinfo transfig fig2dev imagemagick file ghostscript swig doxygen graphviz
+apt-get install --yes pkg-config autopoint python-all-dev python3-all-dev qtbase5-dev
+(cd /tmp; rsync -rvazp /vagrant .)
+(cd /tmp/vagrant; autoreconf -f -i)
+(cd /tmp/vagrant/build-aux; make -f speedo.mk native INSTALL_PREFIX=/tmp/install SELFCHECK=0)
+(cd /tmp/vagrant/build-aux/PLAY/build/gnupg; make check-all)
+SCRIPT
+
+Vagrant.configure("2") do |config|
+ config.vm.box = "debian/stretch64"
+
+ # Use .. for mount. Also, Force NFS vers=3 (instead vers=4) for Debian 8.
+ config.vm.synced_folder "..", "/vagrant", :mount_options => ['nolock,vers=3,tcp,noatime']
+
+ config.vm.provider "libvirt" do |libvirt|
+ libvirt.nested = true
+ libvirt.cpus = 1
+ libvirt.cpu_mode = "host-model"
+ libvirt.memory = 1024
+ libvirt.storage :file, :path => 'vms.qcow2', :size => '1G'
+ end
+
+ config.vm.provision "shell", inline: $script
+
+end
diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk
index c799863..76f712f 100644
--- a/build-aux/speedo.mk
+++ b/build-aux/speedo.mk
@@ -1127,10 +1127,10 @@ dist-source: installer
(set -e;\
tarname="$(INST_NAME)-$(INST_VERSION)_$(BUILD_DATESTR).tar" ;\
[ -f "$$tarname" ] && rm "$$tarname" ;\
- tar -C $(topsrc) -cf "$$tarname" --exclude-backups --exclude-vc \
+ tar -C $(topsrc) -cf "$$tarname" --exclude-backups --exclude-vcs \
--transform='s,^\./,$(INST_NAME)-$(INST_VERSION)/,' \
--anchored --exclude './PLAY' . ;\
- tar --totals -rf "$$tarname" --exclude-backups --exclude-vc \
+ tar --totals -rf "$$tarname" --exclude-backups --exclude-vcs \
--transform='s,^,$(INST_NAME)-$(INST_VERSION)/,' \
PLAY/stamps/stamp-*-00-unpack PLAY/src swdb.lst swdb.lst.sig ;\
[ -f "$$tarname".xz ] && rm "$$tarname".xz;\
diff --git a/build-aux/speedo/w32/g4wihelp.c b/build-aux/speedo/w32/g4wihelp.c
index d62d036..626f3f1 100644
--- a/build-aux/speedo/w32/g4wihelp.c
+++ b/build-aux/speedo/w32/g4wihelp.c
@@ -1159,7 +1159,10 @@ path_remove (HWND hwndParent, int string_size, char *variables,
free (path);
if (! changed)
- return;
+ {
+ free (path_new);
+ return;
+ }
/* Set a key for our CLSID. */
RegCreateKey (root_key, env_reg, &key_handle);
diff --git a/common/Makefile.am b/common/Makefile.am
index 83d82ac..fcbe7ea 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -93,7 +93,8 @@ common_sources = \
server-help.c server-help.h \
name-value.c name-value.h \
recsel.c recsel.h \
- ksba-io-support.c ksba-io-support.h
+ ksba-io-support.c ksba-io-support.h \
+ compliance.c compliance.h
if HAVE_W32_SYSTEM
diff --git a/common/argparse.c b/common/argparse.c
index 2540894..590e6e9 100644
--- a/common/argparse.c
+++ b/common/argparse.c
@@ -918,6 +918,41 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
char *s, *s2;
int i;
+ /* Fill in missing standard options: help, version, warranty and dump-options. */
+ ARGPARSE_OPTS help_opt = ARGPARSE_s_n(ARGPARSE_SHORTOPT_HELP, "help", "@");
+ ARGPARSE_OPTS version_opt = ARGPARSE_s_n(ARGPARSE_SHORTOPT_VERSION, "version", "@");
+ ARGPARSE_OPTS warranty_opt = ARGPARSE_s_n(ARGPARSE_SHORTOPT_WARRANTY, "warranty", "@");
+ ARGPARSE_OPTS dump_options_opt = ARGPARSE_s_n(ARGPARSE_SHORTOPT_DUMP_OPTIONS, "dump-options", "@");
+ int seen_help = 0;
+ int seen_version = 0;
+ int seen_warranty = 0;
+ int seen_dump_options = 0;
+
+ i = 0;
+ while (opts[i].short_opt)
+ {
+ if (opts[i].long_opt)
+ {
+ if (!strcmp(opts[i].long_opt, help_opt.long_opt))
+ seen_help = 1;
+ else if (!strcmp(opts[i].long_opt, version_opt.long_opt))
+ seen_version = 1;
+ else if (!strcmp(opts[i].long_opt, warranty_opt.long_opt))
+ seen_warranty = 1;
+ else if (!strcmp(opts[i].long_opt, dump_options_opt.long_opt))
+ seen_dump_options = 1;
+ }
+ i++;
+ }
+ if (! seen_help)
+ opts[i++] = help_opt;
+ if (! seen_version)
+ opts[i++] = version_opt;
+ if (! seen_warranty)
+ opts[i++] = warranty_opt;
+ if (! seen_dump_options)
+ opts[i++] = dump_options_opt;
+
initialize( arg, NULL, NULL );
argc = *arg->argc;
argv = *arg->argv;
@@ -974,9 +1009,9 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
if ( argpos )
*argpos = '=';
- if ( i < 0 && !strcmp ( "help", s+2) )
+ if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_HELP)
show_help (opts, arg->flags);
- else if ( i < 0 && !strcmp ( "version", s+2) )
+ else if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_VERSION)
{
if (!(arg->flags & ARGPARSE_FLAG_NOVERSION))
{
@@ -984,20 +1019,18 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
exit(0);
}
}
- else if ( i < 0 && !strcmp( "warranty", s+2))
+ else if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_WARRANTY)
{
writestrings (0, strusage (16), "\n", NULL);
exit (0);
}
- else if ( i < 0 && !strcmp( "dump-options", s+2) )
+ else if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_DUMP_OPTIONS)
{
for (i=0; opts[i].short_opt; i++ )
{
if (opts[i].long_opt && !(opts[i].flags & ARGPARSE_OPT_IGNORE))
writestrings (0, "--", opts[i].long_opt, "\n", NULL);
}
- writestrings (0, "--dump-options\n--help\n--version\n--warranty\n",
- NULL);
exit (0);
}
diff --git a/common/argparse.h b/common/argparse.h
index d75b49f..cdd18d9 100644
--- a/common/argparse.h
+++ b/common/argparse.h
@@ -71,6 +71,12 @@ typedef struct
const char *description; /* Optional option description. */
} ARGPARSE_OPTS;
+/* Short options. */
+#define ARGPARSE_SHORTOPT_HELP 32768
+#define ARGPARSE_SHORTOPT_VERSION 32769
+#define ARGPARSE_SHORTOPT_WARRANTY 32770
+#define ARGPARSE_SHORTOPT_DUMP_OPTIONS 32771
+
/* Global flags (ARGPARSE_ARGS). */
#define ARGPARSE_FLAG_KEEP 1 /* Do not remove options form argv. */
@@ -169,7 +175,13 @@ typedef struct
#define ARGPARSE_group(s,d) \
{ (s), NULL, 0, (d) }
-#define ARGPARSE_end() { 0, NULL, 0, NULL }
+/* Placeholder options for help, version, warranty and dump-options. See arg_parse(). */
+#define ARGPARSE_end() \
+ { 0, NULL, 0, NULL }, \
+ { 0, NULL, 0, NULL }, \
+ { 0, NULL, 0, NULL }, \
+ { 0, NULL, 0, NULL }, \
+ { 0, NULL, 0, NULL }
/* Other constants. */
diff --git a/common/compliance.c b/common/compliance.c
new file mode 100644
index 0000000..49aada1
--- /dev/null
+++ b/common/compliance.c
@@ -0,0 +1,590 @@
+/* compliance.c - Functions for compliance modi
+ * Copyright (C) 2017 g10 Code GmbH
+ * Copyright (C) 2017 Bundesamt für Sicherheit in der Informationstechnik
+ *
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <gcrypt.h>
+
+#include "openpgpdefs.h"
+#include "logging.h"
+#include "util.h"
+#include "i18n.h"
+#include "compliance.h"
+
+static int initialized;
+static int module;
+
+/* Initializes the module. Must be called with the current
+ * GNUPG_MODULE_NAME. Checks a few invariants, and tunes the policies
+ * for the given module. */
+void
+gnupg_initialize_compliance (int gnupg_module_name)
+{
+ log_assert (! initialized);
+
+ /* We accept both OpenPGP-style and gcrypt-style algorithm ids.
+ * Assert that they are compatible. */
+ log_assert ((int) GCRY_PK_RSA == (int) PUBKEY_ALGO_RSA);
+ log_assert ((int) GCRY_PK_RSA_E == (int) PUBKEY_ALGO_RSA_E);
+ log_assert ((int) GCRY_PK_RSA_S == (int) PUBKEY_ALGO_RSA_S);
+ log_assert ((int) GCRY_PK_ELG_E == (int) PUBKEY_ALGO_ELGAMAL_E);
+ log_assert ((int) GCRY_PK_DSA == (int) PUBKEY_ALGO_DSA);
+ log_assert ((int) GCRY_PK_ECC == (int) PUBKEY_ALGO_ECDH);
+ log_assert ((int) GCRY_PK_ELG == (int) PUBKEY_ALGO_ELGAMAL);
+ log_assert ((int) GCRY_CIPHER_NONE == (int) CIPHER_ALGO_NONE);
+ log_assert ((int) GCRY_CIPHER_IDEA == (int) CIPHER_ALGO_IDEA);
+ log_assert ((int) GCRY_CIPHER_3DES == (int) CIPHER_ALGO_3DES);
+ log_assert ((int) GCRY_CIPHER_CAST5 == (int) CIPHER_ALGO_CAST5);
+ log_assert ((int) GCRY_CIPHER_BLOWFISH == (int) CIPHER_ALGO_BLOWFISH);
+ log_assert ((int) GCRY_CIPHER_AES == (int) CIPHER_ALGO_AES);
+ log_assert ((int) GCRY_CIPHER_AES192 == (int) CIPHER_ALGO_AES192);
+ log_assert ((int) GCRY_CIPHER_AES256 == (int) CIPHER_ALGO_AES256);
+ log_assert ((int) GCRY_CIPHER_TWOFISH == (int) CIPHER_ALGO_TWOFISH);
+ log_assert ((int) GCRY_MD_MD5 == (int) DIGEST_ALGO_MD5);
+ log_assert ((int) GCRY_MD_SHA1 == (int) DIGEST_ALGO_SHA1);
+ log_assert ((int) GCRY_MD_RMD160 == (int) DIGEST_ALGO_RMD160);
+ log_assert ((int) GCRY_MD_SHA256 == (int) DIGEST_ALGO_SHA256);
+ log_assert ((int) GCRY_MD_SHA384 == (int) DIGEST_ALGO_SHA384);
+ log_assert ((int) GCRY_MD_SHA512 == (int) DIGEST_ALGO_SHA512);
+ log_assert ((int) GCRY_MD_SHA224 == (int) DIGEST_ALGO_SHA224);
+
+ switch (gnupg_module_name)
+ {
+ case GNUPG_MODULE_NAME_GPGSM:
+ case GNUPG_MODULE_NAME_GPG:
+ break;
+
+ default:
+ log_assert (!"no policies for this module");
+ }
+
+ module = gnupg_module_name;
+ initialized = 1;
+}
+
+/* Return true if ALGO with a key of KEYLENGTH is compliant to the
+ * given COMPLIANCE mode. If KEY is not NULL, various bits of
+ * information will be extracted from it. If CURVENAME is not NULL, it
+ * is assumed to be the already computed. ALGO may be either an
+ * OpenPGP-style pubkey_algo_t, or a gcrypt-style enum gcry_pk_algos,
+ * both are compatible from the point of view of this function. */
+int
+gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
+ gcry_mpi_t key[], unsigned int keylength,
+ const char *curvename)
+{
+ enum { is_rsa, is_dsa, is_elg, is_ecc } algotype;
+ int result = 0;
+
+ if (! initialized)
+ return 0;
+
+ switch (algo)
+ {
+ case PUBKEY_ALGO_RSA:
+ case PUBKEY_ALGO_RSA_E:
+ case PUBKEY_ALGO_RSA_S:
+ algotype = is_rsa;
+ break;
+
+ case PUBKEY_ALGO_DSA:
+ algotype = is_dsa;
+ break;
+
+ case PUBKEY_ALGO_ELGAMAL_E:
+ algotype = is_elg;
+ break;
+
+ case PUBKEY_ALGO_ECDH:
+ case PUBKEY_ALGO_ECDSA:
+ case PUBKEY_ALGO_EDDSA:
+ algotype = is_ecc;
+ break;
+
+ case PUBKEY_ALGO_ELGAMAL:
+ return 0; /* Signing with Elgamal is not at all supported. */
+
+ default: /* Unknown. */
+ return 0;
+ }
+
+ if (compliance == CO_DE_VS)
+ {
+ char *curve = NULL;
+
+ switch (algotype)
+ {
+ case is_elg:
+ result = 0;
+ break;
+
+ case is_rsa:
+ result = (keylength == 2048
+ || keylength == 3072
+ || keylength == 4096);
+ break;
+
+ case is_dsa:
+ if (key)
+ {
+ size_t P = gcry_mpi_get_nbits (key[0]);
+ size_t Q = gcry_mpi_get_nbits (key[1]);
+ result = (Q == 256
+ && (P == 2048 || P == 3072));
+ }
+ break;
+
+ case is_ecc:
+ if (!curvename && key)
+ {
+ curve = openpgp_oid_to_str (key[0]);
+ curvename = openpgp_oid_to_curve (curve, 0);
+ if (!curvename)
+ curvename = curve;
+ }
+
+ result = (curvename
+ && (algo == PUBKEY_ALGO_ECDH
+ || algo == PUBKEY_ALGO_ECDSA)
+ && (!strcmp (curvename, "brainpoolP256r1")
+ || !strcmp (curvename, "brainpoolP384r1")
+ || !strcmp (curvename, "brainpoolP512r1")));
+ break;
+
+ default:
+ result = 0;
+ }
+ xfree (curve);
+ }
+ else
+ {
+ result = 1; /* Assume compliance. */
+ }
+
+ return result;
+}
+
+
+/* Return true if ALGO with the given KEYLENGTH is allowed in the
+ * given COMPLIANCE mode. USE specifies for which use case the
+ * predicate is evaluated. This way policies can be strict in what
+ * they produce, and liberal in what they accept. */
+int
+gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
+ enum pk_use_case use, int algo, gcry_mpi_t key[],
+ unsigned int keylength, const char *curvename)
+{
+ int result = 0;
+
+ if (! initialized)
+ return 1;
+
+ switch (compliance)
+ {
+ case CO_DE_VS:
+ switch (algo)
+ {
+ case PUBKEY_ALGO_RSA:
+ case PUBKEY_ALGO_RSA_E:
+ case PUBKEY_ALGO_RSA_S:
+ switch (use)
+ {
+ case PK_USE_DECRYPTION:
+ case PK_USE_VERIFICATION:
+ result = 1;
+ break;
+ case PK_USE_ENCRYPTION:
+ case PK_USE_SIGNING:
+ result = (keylength == 2048
+ || keylength == 3072
+ || keylength == 4096);
+ break;
+ default:
+ log_assert (!"reached");
+ }
+ break;
+
+ case PUBKEY_ALGO_DSA:
+ if (use == PK_USE_VERIFICATION)
+ result = 1;
+ else if (use == PK_USE_SIGNING && key)
+ {
+ size_t P = gcry_mpi_get_nbits (key[0]);
+ size_t Q = gcry_mpi_get_nbits (key[1]);
+ result = (Q == 256 && (P == 2048 || P == 3072));
+ }
+ break;
+
+ case PUBKEY_ALGO_ELGAMAL:
+ case PUBKEY_ALGO_ELGAMAL_E:
+ result = (use == PK_USE_DECRYPTION);
+ break;
+
+ case PUBKEY_ALGO_ECDH:
+ if (use == PK_USE_DECRYPTION)
+ result = 1;
+ else if (use == PK_USE_ENCRYPTION)
+ {
+ char *curve = NULL;
+
+ if (!curvename && key)
+ {
+ curve = openpgp_oid_to_str (key[0]);
+ curvename = openpgp_oid_to_curve (curve, 0);
+ if (!curvename)
+ curvename = curve;
+ }
+
+ result = (curvename
+ && (!strcmp (curvename, "brainpoolP256r1")
+ || !strcmp (curvename, "brainpoolP384r1")
+ || !strcmp (curvename, "brainpoolP512r1")));
+
+ xfree (curve);
+ }
+ break;
+
+ case PUBKEY_ALGO_ECDSA:
+ if (use == PK_USE_VERIFICATION)
+ result = 1;
+ else
+ {
+ char *curve = NULL;
+
+ if (! curvename && key)
+ {
+ curve = openpgp_oid_to_str (key[0]);
+ curvename = openpgp_oid_to_curve (curve, 0);
+ if (!curvename)
+ curvename = curve;
+ }
+
+ result = (use == PK_USE_SIGNING
+ && curvename
+ && (!strcmp (curvename, "brainpoolP256r1")
+ || !strcmp (curvename, "brainpoolP384r1")
+ || !strcmp (curvename, "brainpoolP512r1")));
+ xfree (curve);
+ }
+ break;
+
+
+ case PUBKEY_ALGO_EDDSA:
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ /* The default policy is to allow all algorithms. */
+ result = 1;
+ }
+
+ return result;
+}
+
+
+/* Return true if (CIPHER, MODE) is compliant to the given COMPLIANCE mode. */
+int
+gnupg_cipher_is_compliant (enum gnupg_compliance_mode compliance,
+ cipher_algo_t cipher,
+ enum gcry_cipher_modes mode)
+{
+ if (! initialized)
+ return 0;
+
+ switch (compliance)
+ {
+ case CO_DE_VS:
+ switch (cipher)
+ {
+ case CIPHER_ALGO_AES:
+ case CIPHER_ALGO_AES192:
+ case CIPHER_ALGO_AES256:
+ case CIPHER_ALGO_3DES:
+ switch (module)
+ {
+ case GNUPG_MODULE_NAME_GPG:
+ return mode == GCRY_CIPHER_MODE_CFB;
+ case GNUPG_MODULE_NAME_GPGSM:
+ return mode == GCRY_CIPHER_MODE_CBC;
+ }
+ log_assert (!"reached");
+
+ default:
+ return 0;
+ }
+ log_assert (!"reached");
+
+ default:
+ return 0;
+ }
+
+ log_assert (!"reached");
+}
+
+
+/* Return true if CIPHER is allowed in the given COMPLIANCE mode. If
+ * PRODUCER is true, the predicate is evaluated for the producer, if
+ * false for the consumer. This way policies can be strict in what
+ * they produce, and liberal in what they accept. */
+int
+gnupg_cipher_is_allowed (enum gnupg_compliance_mode compliance, int producer,
+ cipher_algo_t cipher,
+ enum gcry_cipher_modes mode)
+{
+ if (! initialized)
+ return 1;
+
+ switch (compliance)
+ {
+ case CO_DE_VS:
+ switch (cipher)
+ {
+ case CIPHER_ALGO_AES:
+ case CIPHER_ALGO_AES192:
+ case CIPHER_ALGO_AES256:
+ case CIPHER_ALGO_3DES:
+ switch (module)
+ {
+ case GNUPG_MODULE_NAME_GPG:
+ return (mode == GCRY_CIPHER_MODE_NONE
+ || mode == GCRY_CIPHER_MODE_CFB);
+ case GNUPG_MODULE_NAME_GPGSM:
+ return (mode == GCRY_CIPHER_MODE_NONE
+ || mode == GCRY_CIPHER_MODE_CBC);
+ }
+ log_assert (!"reached");
+
+ case CIPHER_ALGO_BLOWFISH:
+ case CIPHER_ALGO_CAMELLIA128:
+ case CIPHER_ALGO_CAMELLIA192:
+ case CIPHER_ALGO_CAMELLIA256:
+ case CIPHER_ALGO_CAST5:
+ case CIPHER_ALGO_IDEA:
+ case CIPHER_ALGO_TWOFISH:
+ return (module == GNUPG_MODULE_NAME_GPG
+ && (mode == GCRY_CIPHER_MODE_NONE
+ || mode == GCRY_CIPHER_MODE_CFB)
+ && ! producer);
+ default:
+ return 0;
+ }
+ log_assert (!"reached");
+
+ default:
+ /* The default policy is to allow all algorithms. */
+ return 1;
+ }
+
+ log_assert (!"reached");
+}
+
+
+/* Return true if DIGEST is compliant to the given COMPLIANCE mode. */
+int
+gnupg_digest_is_compliant (enum gnupg_compliance_mode compliance,
+ digest_algo_t digest)
+{
+ if (! initialized)
+ return 0;
+
+ switch (compliance)
+ {
+ case CO_DE_VS:
+ switch (digest)
+ {
+ case DIGEST_ALGO_SHA256:
+ case DIGEST_ALGO_SHA384:
+ case DIGEST_ALGO_SHA512:
+ return 1;
+ default:
+ return 0;
+ }
+ log_assert (!"reached");
+
+ default:
+ return 0;
+ }
+
+ log_assert (!"reached");
+}
+
+
+/* Return true if DIGEST is allowed in the given COMPLIANCE mode. If
+ * PRODUCER is true, the predicate is evaluated for the producer, if
+ * false for the consumer. This way policies can be strict in what
+ * they produce, and liberal in what they accept. */
+int
+gnupg_digest_is_allowed (enum gnupg_compliance_mode compliance, int producer,
+ digest_algo_t digest)
+{
+ if (! initialized)
+ return 1;
+
+ switch (compliance)
+ {
+ case CO_DE_VS:
+ switch (digest)
+ {
+ case DIGEST_ALGO_SHA256:
+ case DIGEST_ALGO_SHA384:
+ case DIGEST_ALGO_SHA512:
+ return 1;
+ case DIGEST_ALGO_SHA1:
+ case DIGEST_ALGO_SHA224:
+ case DIGEST_ALGO_RMD160:
+ return ! producer;
+ case DIGEST_ALGO_MD5:
+ return ! producer && module == GNUPG_MODULE_NAME_GPGSM;
+ default:
+ return 0;
+ }
+ log_assert (!"reached");
+
+ default:
+ /* The default policy is to allow all algorithms. */
+ return 1;
+ }
+
+ log_assert (!"reached");
+}
+
+
+/* Return True if the random number generator is compliant in
+ * COMPLIANCE mode. */
+int
+gnupg_rng_is_compliant (enum gnupg_compliance_mode compliance)
+{
+ static int result = -1;
+
+ if (result != -1)
+ ; /* Use cached result. */
+ else if (compliance == CO_DE_VS)
+ {
+ /* In DE_VS mode under Windows we require that the JENT RNG
+ * is active. */
+#ifdef HAVE_W32_SYSTEM
+# if GCRYPT_VERSION_NUMBER >= 0x010800
+ char *buf;
+ char *fields[5];
+
+ buf = gcry_get_config (0, "rng-type");
+ if (buf
+ && split_fields_colon (buf, fields, DIM (fields)) >= 5
+ && atoi (fields[4]) > 0)
+ result = 1;
+ else
+ result = 0;
+ gcry_free (buf);
+# else
+ result = 0; /* No JENT - can't be compliant. */
+# endif
+#else /*!HAVE_W32_SYSTEM*/
+ result = 1; /* Not Windows - RNG is good. */
+#endif /*!HAVE_W32_SYSTEM*/
+ }
+ else
+ result = 1;
+
+ return result;
+}
+
+
+const char *
+gnupg_status_compliance_flag (enum gnupg_compliance_mode compliance)
+{
+ switch (compliance)
+ {
+ case CO_GNUPG:
+ return "8";
+ case CO_RFC4880:
+ case CO_RFC2440:
+ case CO_PGP6:
+ case CO_PGP7:
+ case CO_PGP8:
+ log_assert (!"no status code assigned for this compliance mode");
+ case CO_DE_VS:
+ return "23";
+ }
+ log_assert (!"invalid compliance mode");
+}
+
+
+/* Parse the value of --compliance. Returns the value corresponding
+ * to the given STRING according to OPTIONS of size LENGTH, or -1
+ * indicating that the lookup was unsuccessful, or the list of options
+ * was printed. If quiet is false, an additional hint to use 'help'
+ * is printed on unsuccessful lookups. */
+int
+gnupg_parse_compliance_option (const char *string,
+ struct gnupg_compliance_option options[],
+ size_t length,
+ int quiet)
+{
+ size_t i;
+
+ if (! ascii_strcasecmp (string, "help"))
+ {
+ log_info (_("valid values for option '%s':\n"), "--compliance");
+ for (i = 0; i < length; i++)
+ log_info (" %s\n", options[i].keyword);
+ return -1;
+ }
+
+ for (i = 0; i < length; i++)
+ if (! ascii_strcasecmp (string, options[i].keyword))
+ return options[i].value;
+
+ log_error (_("invalid value for option '%s'\n"), "--compliance");
+ if (! quiet)
+ log_info (_("(use \"help\" to list choices)\n"));
+ return -1;
+}
+
+
+/* Return the command line option for the given COMPLIANCE mode. */
+const char *
+gnupg_compliance_option_string (enum gnupg_compliance_mode compliance)
+{
+ switch (compliance)
+ {
+ case CO_GNUPG: return "--compliance=gnupg";
+ case CO_RFC4880: return "--compliance=openpgp";
+ case CO_RFC2440: return "--compliance=rfc2440";
+ case CO_PGP6: return "--compliance=pgp6";
+ case CO_PGP7: return "--compliance=pgp7";
+ case CO_PGP8: return "--compliance=pgp8";
+ case CO_DE_VS: return "--compliance=de-vs";
+ }
+
+ log_assert (!"invalid compliance mode");
+}
diff --git a/common/compliance.h b/common/compliance.h
new file mode 100644
index 0000000..2076e79
--- /dev/null
+++ b/common/compliance.h
@@ -0,0 +1,88 @@
+/* compliance.h - Definitions for compliance modi
+ * Copyright (C) 2017 g10 Code GmbH
+ * Copyright (C) 2017 Bundesamt für Sicherheit in der Informationstechnik
+ *
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef GNUPG_COMMON_COMPLIANCE_H
+#define GNUPG_COMMON_COMPLIANCE_H
+
+#include <gcrypt.h>
+#include "openpgpdefs.h"
+
+void gnupg_initialize_compliance (int gnupg_module_name);
+
+enum gnupg_compliance_mode
+ {
+ CO_GNUPG, CO_RFC4880, CO_RFC2440,
+ CO_PGP6, CO_PGP7, CO_PGP8, CO_DE_VS
+ };
+
+enum pk_use_case
+ {
+ PK_USE_ENCRYPTION, PK_USE_DECRYPTION,
+ PK_USE_SIGNING, PK_USE_VERIFICATION,
+ };
+
+int gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
+ gcry_mpi_t key[], unsigned int keylength,
+ const char *curvename);
+int gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
+ enum pk_use_case use, int algo, gcry_mpi_t key[],
+ unsigned int keylength, const char *curvename);
+int gnupg_cipher_is_compliant (enum gnupg_compliance_mode compliance,
+ cipher_algo_t cipher,
+ enum gcry_cipher_modes mode);
+int gnupg_cipher_is_allowed (enum gnupg_compliance_mode compliance,
+ int producer,
+ cipher_algo_t cipher,
+ enum gcry_cipher_modes mode);
+int gnupg_digest_is_compliant (enum gnupg_compliance_mode compliance,
+ digest_algo_t digest);
+int gnupg_digest_is_allowed (enum gnupg_compliance_mode compliance,
+ int producer,
+ digest_algo_t digest);
+int gnupg_rng_is_compliant (enum gnupg_compliance_mode compliance);
+
+const char *gnupg_status_compliance_flag (enum gnupg_compliance_mode
+ compliance);
+
+struct gnupg_compliance_option
+{
+ const char *keyword;
+ int value;
+};
+
+int gnupg_parse_compliance_option (const char *string,
+ struct gnupg_compliance_option options[],
+ size_t length,
+ int quiet);
+const char *gnupg_compliance_option_string (enum gnupg_compliance_mode
+ compliance);
+
+
+#endif /*GNUPG_COMMON_COMPLIANCE_H*/
diff --git a/common/homedir.c b/common/homedir.c
index fce6d44..149e1ec 100644
--- a/common/homedir.c
+++ b/common/homedir.c
@@ -247,7 +247,7 @@ default_homedir (void)
{
if (!dir || !*dir)
{
- char *tmp;
+ char *tmp, *p;
tmp = read_w32_registry_string (NULL,
GNUPG_REGISTRY_DIR,
@@ -258,7 +258,13 @@ default_homedir (void)
tmp = NULL;
}
if (tmp)
- saved_dir = tmp;
+ {
+ /* Strip trailing backslashes. */
+ p = tmp + strlen (tmp) - 1;
+ while (p > tmp && *p == '\\')
+ *p-- = 0;
+ saved_dir = tmp;
+ }
}
if (!saved_dir)
@@ -267,10 +273,27 @@ default_homedir (void)
dir = saved_dir;
}
#endif /*HAVE_W32_SYSTEM*/
+
if (!dir || !*dir)
dir = GNUPG_DEFAULT_HOMEDIR;
- else if (!is_gnupg_default_homedir (dir))
- non_default_homedir = 1;
+ else
+ {
+ /* Strip trailing slashes if any. */
+ if (dir[strlen (dir)-1] == '/')
+ {
+ char *tmp, *p;
+
+ tmp = xstrdup (dir);
+ p = tmp + strlen (tmp) - 1;
+ while (p > tmp && *p == '/')
+ *p-- = 0;
+
+ dir = tmp;
+ }
+
+ if (!is_gnupg_default_homedir (dir))
+ non_default_homedir = 1;
+ }
return dir;
}
@@ -403,12 +426,40 @@ w32_commondir (void)
void
gnupg_set_homedir (const char *newdir)
{
+ char *tmp = NULL;
+
if (!newdir || !*newdir)
newdir = default_homedir ();
- else if (!is_gnupg_default_homedir (newdir))
- non_default_homedir = 1;
+ else
+ {
+ /* Remove trailing slashes from NEWSDIR. */
+ if (newdir[strlen (newdir)-1] == '/'
+#ifdef HAVE_W32_SYSTEM
+ || newdir[strlen (newdir)-1] == '\\'
+#endif
+ )
+ {
+ char *p;
+
+ tmp = xstrdup (newdir);
+ p = tmp + strlen (tmp) - 1;
+ while (p > tmp
+ && (*p == '/'
+#ifdef HAVE_W32_SYSTEM
+ || *p == '\\'
+#endif
+ )
+ )
+ *p-- = 0;
+
+ newdir = tmp;
+ }
+ if (!is_gnupg_default_homedir (newdir))
+ non_default_homedir = 1;
+ }
xfree (the_gnupg_homedir);
the_gnupg_homedir = make_absfilename (newdir, NULL);;
+ xfree (tmp);
}
@@ -433,6 +484,34 @@ gnupg_default_homedir_p (void)
}
+/* Return the directory name used by daemons for their current working
+ * directory. */
+const char *
+gnupg_daemon_rootdir (void)
+{
+#ifdef HAVE_W32_SYSTEM
+ static char *name;
+
+ if (!name)
+ {
+ char path[MAX_PATH];
+ size_t n;
+
+ n = GetSystemDirectoryA (path, sizeof path);
+ if (!n || n >= sizeof path)
+ name = xstrdup ("/"); /* Error - use the curret top dir instead. */
+ else
+ name = xstrdup (path);
+ }
+
+ return name;
+
+#else /*!HAVE_W32_SYSTEM*/
+ return "/";
+#endif /*!HAVE_W32_SYSTEM*/
+}
+
+
/* Helper for gnupg-socketdir. This is a global function, so that
* gpgconf can use it for its --create-socketdir command. If
* SKIP_CHECKS is set permission checks etc. are not done. The
diff --git a/common/logging.c b/common/logging.c
index bc5f72b..c4eaca4 100644
--- a/common/logging.c
+++ b/common/logging.c
@@ -472,7 +472,8 @@ set_file_fd (const char *name, int fd)
/* Close an open log stream. */
if (logstream)
{
- es_fclose (logstream);
+ if (logstream != es_stderr)
+ es_fclose (logstream);
logstream = NULL;
}
diff --git a/common/miscellaneous.c b/common/miscellaneous.c
index c9c603d..caeb66f 100644
--- a/common/miscellaneous.c
+++ b/common/miscellaneous.c
@@ -228,6 +228,16 @@ print_utf8_buffer (estream_t stream, const void *p, size_t n)
do_print_utf8_buffer (stream, p, n, NULL, NULL);
}
+
+void
+print_utf8_string (estream_t stream, const char *p)
+{
+ if (!p)
+ p = "";
+ do_print_utf8_buffer (stream, p, strlen (p), NULL, NULL);
+}
+
+
/* Write LENGTH bytes of BUFFER to FP as a hex encoded string.
RESERVED must be 0. */
void
diff --git a/common/ssh-utils.c b/common/ssh-utils.c
index 60aa07b..38d6e8a 100644
--- a/common/ssh-utils.c
+++ b/common/ssh-utils.c
@@ -64,13 +64,17 @@ is_eddsa (gcry_sexp_t keyparms)
return result;
}
+/* Dummy functions for es_mopen. */
+static void *dummy_realloc (void *mem, size_t size) { (void) size; return mem; }
+static void dummy_free (void *mem) { (void) mem; }
-/* 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. */
+/* Return the Secure Shell type fingerprint for KEY using digest ALGO.
+ 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. */
static gpg_error_t
-get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, int as_string)
+get_fingerprint (gcry_sexp_t key, int algo,
+ void **r_fpr, size_t *r_len, int as_string)
{
gpg_error_t err;
gcry_sexp_t list = NULL;
@@ -111,7 +115,7 @@ get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, int as_string)
goto leave;
}
- err = gcry_md_open (&md, GCRY_MD_MD5, 0);
+ err = gcry_md_open (&md, algo, 0);
if (err)
goto leave;
@@ -229,23 +233,87 @@ get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, int as_string)
}
}
- *r_fpr = gcry_malloc (as_string? 61:20);
- if (!*r_fpr)
- {
- err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
- goto leave;
- }
-
if (as_string)
{
- bin2hexcolon (gcry_md_read (md, GCRY_MD_MD5), 16, *r_fpr);
- *r_len = 3*16+1;
- strlwr (*r_fpr);
+ const char *algo_name;
+ char *fpr;
+
+ /* Prefix string with the algorithm name and a colon. */
+ algo_name = gcry_md_algo_name (algo);
+ *r_fpr = xtrymalloc (strlen (algo_name) + 1 + 3 * gcry_md_get_algo_dlen (algo) + 1);
+ if (*r_fpr == NULL)
+ {
+ err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+ goto leave;
+ }
+
+ strncpy (*r_fpr, algo_name, strlen (algo_name));
+ fpr = (char *) *r_fpr + strlen (algo_name);
+ *fpr++ = ':';
+
+ if (algo == GCRY_MD_MD5)
+ {
+ bin2hexcolon (gcry_md_read (md, algo), gcry_md_get_algo_dlen (algo), fpr);
+ strlwr (fpr);
+ }
+ else
+ {
+ struct b64state b64s;
+ estream_t stream;
+ char *p;
+ long int len;
+
+ /* Write the base64-encoded hash to fpr. */
+ stream = es_mopen (fpr, 3 * gcry_md_get_algo_dlen (algo) + 1, 0,
+ 0, dummy_realloc, dummy_free, "w");
+ if (stream == NULL)
+ {
+ err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+ goto leave;
+ }
+
+ err = b64enc_start_es (&b64s, stream, "");
+ if (err)
+ {
+ es_fclose (stream);
+ goto leave;
+ }
+
+ err = b64enc_write (&b64s,
+ gcry_md_read (md, algo), gcry_md_get_algo_dlen (algo));
+ if (err)
+ {
+ es_fclose (stream);
+ goto leave;
+ }
+
+ /* Finish, get the length, and close the stream. */
+ err = b64enc_finish (&b64s);
+ len = es_ftell (stream);
+ es_fclose (stream);
+ if (err)
+ goto leave;
+
+ /* Terminate. */
+ fpr[len] = 0;
+
+ /* Strip the trailing padding characters. */
+ for (p = fpr + len - 1; p > fpr && *p == '='; p--)
+ *p = 0;
+ }
+
+ *r_len = strlen (*r_fpr) + 1;
}
else
{
- memcpy (*r_fpr, gcry_md_read (md, GCRY_MD_MD5), 16);
- *r_len = 16;
+ *r_len = gcry_md_get_algo_dlen (algo);
+ *r_fpr = xtrymalloc (*r_len);
+ if (!*r_fpr)
+ {
+ err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+ goto leave;
+ }
+ memcpy (*r_fpr, gcry_md_read (md, algo), *r_len);
}
err = 0;
@@ -257,28 +325,30 @@ get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, int as_string)
return err;
}
-/* 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. */
+/* Return the Secure Shell type fingerprint for KEY using digest ALGO.
+ 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. */
gpg_error_t
-ssh_get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len)
+ssh_get_fingerprint (gcry_sexp_t key, int algo,
+ void **r_fpr, size_t *r_len)
{
- return get_fingerprint (key, r_fpr, r_len, 0);
+ return get_fingerprint (key, algo, 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. */
+/* Return the Secure Shell type fingerprint for KEY using digest ALGO
+ 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. */
gpg_error_t
-ssh_get_fingerprint_string (gcry_sexp_t key, char **r_fprstr)
+ssh_get_fingerprint_string (gcry_sexp_t key, int algo, char **r_fprstr)
{
gpg_error_t err;
size_t dummy;
void *string;
- err = get_fingerprint (key, &string, &dummy, 1);
+ err = get_fingerprint (key, algo, &string, &dummy, 1);
*r_fprstr = string;
return err;
}
diff --git a/common/ssh-utils.h b/common/ssh-utils.h
index 36d38a3..53d9f55 100644
--- a/common/ssh-utils.h
+++ b/common/ssh-utils.h
@@ -31,9 +31,11 @@
#define GNUPG_COMMON_SSH_UTILS_H
-gpg_error_t ssh_get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len);
+gpg_error_t ssh_get_fingerprint (gcry_sexp_t key, int algo,
+ void **r_fpr, size_t *r_len);
-gpg_error_t ssh_get_fingerprint_string (gcry_sexp_t key, char **r_fprstr);
+gpg_error_t ssh_get_fingerprint_string (gcry_sexp_t key, int algo,
+ char **r_fprstr);
#endif /*GNUPG_COMMON_SSH_UTILS_H*/
diff --git a/common/status.h b/common/status.h
index 8831a0f..dc62f36 100644
--- a/common/status.h
+++ b/common/status.h
@@ -141,6 +141,10 @@ enum
STATUS_TOFU_STATS_SHORT,
STATUS_TOFU_STATS_LONG,
+ STATUS_ENCRYPTION_COMPLIANCE_MODE,
+ STATUS_DECRYPTION_COMPLIANCE_MODE,
+ STATUS_VERIFICATION_COMPLIANCE_MODE,
+
STATUS_TRUNCATED,
STATUS_MOUNTPOINT,
STATUS_BLOCKDEV,
diff --git a/common/stringhelp.c b/common/stringhelp.c
index 3b481e8..0abac8a 100644
--- a/common/stringhelp.c
+++ b/common/stringhelp.c
@@ -1339,6 +1339,42 @@ split_fields (char *string, char **array, int arraysize)
}
+/* Split a string into colon delimited fields A pointer to each field
+ * is stored in ARRAY. Stop splitting at ARRAYSIZE fields. The
+ * function modifies STRING. The number of parsed fields is returned.
+ * Note that leading and trailing spaces are not removed from the fields.
+ * Example:
+ *
+ * char *fields[2];
+ * if (split_fields (string, fields, DIM (fields)) < 2)
+ * return // Not enough args.
+ * foo (fields[0]);
+ * foo (fields[1]);
+ */
+int
+split_fields_colon (char *string, char **array, int arraysize)
+{
+ int n = 0;
+ char *p, *pend;
+
+ p = string;
+ do
+ {
+ if (n == arraysize)
+ break;
+ array[n++] = p;
+ pend = strchr (p, ':');
+ if (!pend)
+ break;
+ *pend++ = 0;
+ p = pend;
+ }
+ while (*p);
+
+ return n;
+}
+
+
/* Version number parsing. */
diff --git a/common/stringhelp.h b/common/stringhelp.h
index a643f35..5b07af9 100644
--- a/common/stringhelp.h
+++ b/common/stringhelp.h
@@ -151,6 +151,10 @@ char **strtokenize (const char *string, const char *delim);
* provided ARRAY. */
int split_fields (char *string, char **array, int arraysize);
+/* Split STRING into colon delimited fields and store them in the
+ * provided ARRAY. */
+int split_fields_colon (char *string, char **array, int arraysize);
+
/* Return True if MYVERSION is greater or equal than REQ_VERSION. */
int compare_version_strings (const char *my_version, const char *req_version);
diff --git a/common/sysutils.c b/common/sysutils.c
index ea0acdb..e90010c 100644
--- a/common/sysutils.c
+++ b/common/sysutils.c
@@ -796,6 +796,15 @@ gnupg_mkdir (const char *name, const char *modestr)
}
+/* A simple wrapper around chdir. NAME is expected to be utf8
+ * encoded. */
+int
+gnupg_chdir (const char *name)
+{
+ return chdir (name);
+}
+
+
/* A wrapper around chmod 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 the same
@@ -1125,6 +1134,43 @@ w32_get_user_sid (void)
/* Support for inotify under Linux. */
+/* Store a new inotify file handle for FNAME at R_FD or return an
+ * error code. This file descriptor watch the removal of FNAME. */
+gpg_error_t
+gnupg_inotify_watch_delete_self (int *r_fd, const char *fname)
+{
+#if HAVE_INOTIFY_INIT
+ gpg_error_t err;
+ int fd;
+
+ *r_fd = -1;
+
+ if (!fname)
+ return my_error (GPG_ERR_INV_VALUE);
+
+ fd = inotify_init ();
+ if (fd == -1)
+ return my_error_from_syserror ();
+
+ if (inotify_add_watch (fd, fname, IN_DELETE_SELF) == -1)
+ {
+ err = my_error_from_syserror ();
+ close (fd);
+ return err;
+ }
+
+ *r_fd = fd;
+ return 0;
+#else /*!HAVE_INOTIFY_INIT*/
+
+ (void)fname;
+ *r_fd = -1;
+ return my_error (GPG_ERR_NOT_SUPPORTED);
+
+#endif /*!HAVE_INOTIFY_INIT*/
+}
+
+
/* Store a new inotify file handle for SOCKET_NAME at R_FD or return
* an error code. */
gpg_error_t
diff --git a/common/sysutils.h b/common/sysutils.h
index ecd9f84..009b14b 100644
--- a/common/sysutils.h
+++ b/common/sysutils.h
@@ -65,7 +65,8 @@ void gnupg_allow_set_foregound_window (pid_t pid);
int gnupg_remove (const char *fname);
gpg_error_t gnupg_rename_file (const char *oldname, const char *newname,
int *block_signals);
-int gnupg_mkdir (const char *name, const char *modestr);
+int gnupg_mkdir (const char *name, const char *modestr);
+int gnupg_chdir (const char *name);
int gnupg_chmod (const char *name, const char *modestr);
char *gnupg_mkdtemp (char *template);
int gnupg_setenv (const char *name, const char *value, int overwrite);
@@ -74,6 +75,7 @@ char *gnupg_getcwd (void);
char *gnupg_get_socket_name (int fd);
int gnupg_fd_valid (int fd);
+gpg_error_t gnupg_inotify_watch_delete_self (int *r_fd, const char *fname);
gpg_error_t gnupg_inotify_watch_socket (int *r_fd, const char *socket_name);
int gnupg_inotify_has_name (int fd, const char *name);
diff --git a/common/t-ssh-utils.c b/common/t-ssh-utils.c
index f63ea95..1c9b87b 100644
--- a/common/t-ssh-utils.c
+++ b/common/t-ssh-utils.c
@@ -28,7 +28,12 @@
#include "ssh-utils.h"
-static struct { const char *key; const char *fpr; } sample_keys[] = {
+static struct
+{
+ const char *key;
+ const char *fpr_md5;
+ const char *fpr_sha256;
+} sample_keys[] = {
{ "(protected-private-key "
"(rsa "
"(n #"
@@ -70,7 +75,8 @@ static struct { const char *key; const char *fpr; } sample_keys[] = {
")"
"(comment passphrase_is_abc)"
")",
- "c7:c6:a7:ec:04:6c:87:59:54:f2:88:58:09:e0:f2:b1"
+ "MD5:c7:c6:a7:ec:04:6c:87:59:54:f2:88:58:09:e0:f2:b1",
+ "SHA256:ksKb4DKk2SFX56GRtpt0szBnyjiYARSb2FNlUb7snnE"
},
{
"(protected-private-key "
@@ -99,7 +105,8 @@ static struct { const char *key; const char *fpr; } sample_keys[] = {
")"
"(comment sample_dsa_passphrase_is_abc)"
")",
- "2d:b1:70:1a:04:9e:41:a3:ce:27:a5:c7:22:fe:3a:a3"
+ "MD5:2d:b1:70:1a:04:9e:41:a3:ce:27:a5:c7:22:fe:3a:a3",
+ "SHA256:z8+8HEuD/5QpegGS4tSK02dJF+a6o2V67VM2gOPz9oQ"
},
{ /* OpenSSH 6.7p1 generated key: */
"(protected-private-key "
@@ -118,7 +125,8 @@ static struct { const char *key; const char *fpr; } sample_keys[] = {
")"
"(comment \"ecdsa w/o comment\")"
")", /* Passphrase="abc" */
- "93:4f:08:02:7d:cb:16:9b:0c:39:21:4b:cf:28:5a:19"
+ "MD5:93:4f:08:02:7d:cb:16:9b:0c:39:21:4b:cf:28:5a:19",
+ "SHA256:zSj4uXfE1hlQnESD2LO723fMGXsNwzHrfqOfqep37is"
},
{ /* OpenSSH 6.7p1 generated key: */
"(protected-private-key "
@@ -139,7 +147,8 @@ static struct { const char *key; const char *fpr; } sample_keys[] = {
")"
"(comment \"ecdsa w/o comment\")"
")", /* Passphrase="abc" */
- "a3:cb:44:c8:56:15:25:62:85:fd:e8:04:7a:26:dc:76"
+ "MD5:a3:cb:44:c8:56:15:25:62:85:fd:e8:04:7a:26:dc:76",
+ "SHA256:JuQh5fjduynuuTEwI9C6yAKK1NnLX9PPd7TP0qZfbGs"
},
{ /* OpenSSH 6.7p1 generated key: */
"(protected-private-key "
@@ -161,7 +170,8 @@ static struct { const char *key; const char *fpr; } sample_keys[] = {
")"
"(comment \"ecdsa w/o comment\")"
")", /* Passphrase="abc" */
- "1e:a6:94:ab:bd:81:73:5f:22:bc:0e:c7:89:f6:68:df"
+ "MD5:1e:a6:94:ab:bd:81:73:5f:22:bc:0e:c7:89:f6:68:df",
+ "SHA256:+pbRyYa2UBwDki1k4Wziu2CKrdJIbZM/hOWOQ/sNe/0"
},
{ /* OpenSSH 6.7p1 generated key: */
"(protected-private-key "
@@ -180,7 +190,8 @@ static struct { const char *key; const char *fpr; } sample_keys[] = {
")"
"(comment \"eddsa w/o comment\")"
")", /* Passphrase="abc" */
- "f1:fa:c8:a6:40:bb:b9:a1:65:d7:62:65:ac:26:78:0e"
+ "MD5:f1:fa:c8:a6:40:bb:b9:a1:65:d7:62:65:ac:26:78:0e",
+ "SHA256:yhwBfYnTOnSXcWf1EOPo+oIIpNJ6w/bG36udZ96MmsQ"
},
{
NULL,
@@ -259,10 +270,44 @@ main (int argc, char **argv)
char *string;
int idx;
- if (argc == 2)
+ /* --dump-keys dumps the keys as KEYGRIP.key.IDX. Useful to compute
+ fingerprints to enhance the test vectors. */
+ if (argc == 2 && strcmp (argv[1], "--dump-keys") == 0)
+ for (idx=0; sample_keys[idx].key; idx++)
+ {
+ FILE *s;
+ char *name;
+ char grip[20];
+ char *hexgrip;
+
+ err = keygrip_from_canon_sexp (sample_keys[idx].key,
+ strlen (sample_keys[idx].key),
+ grip);
+ if (err)
+ {
+ fprintf (stderr, "%s:%d: error computing keygrip: %s\n",
+ __FILE__, __LINE__, gpg_strerror (err));
+ exit (1);
+ }
+ hexgrip = bin2hex (grip, 20, NULL);
+
+ name = xtryasprintf ("%s.key.%d", hexgrip, idx);
+ s = fopen (name, "w");
+ if (s == NULL)
+ {
+ fprintf (stderr, "%s:%d: error opening file: %s\n",
+ __FILE__, __LINE__, gpg_strerror (gpg_error_from_syserror ()));
+ exit (1);
+ }
+ xfree (name);
+ fprintf (s, "%s", sample_keys[idx].key);
+ fclose (s);
+ }
+ else if (argc == 2)
{
key = read_key (argv[1]);
- err = ssh_get_fingerprint_string (key, &string);
+
+ err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &string);
if (err)
{
fprintf (stderr, "%s:%d: error getting fingerprint: %s\n",
@@ -271,6 +316,17 @@ main (int argc, char **argv)
}
puts (string);
xfree (string);
+
+ err = ssh_get_fingerprint_string (key, GCRY_MD_SHA256, &string);
+ if (err)
+ {
+ fprintf (stderr, "%s:%d: error getting fingerprint: %s\n",
+ __FILE__, __LINE__, gpg_strerror (err));
+ exit (1);
+ }
+ puts (string);
+ xfree (string);
+
gcry_sexp_release (key);
}
else
@@ -287,8 +343,27 @@ main (int argc, char **argv)
exit (1);
}
- err = ssh_get_fingerprint_string (key, &string);
- gcry_sexp_release (key);
+ err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &string);
+ if (err)
+ {
+ fprintf (stderr, "%s:%d: error getting fingerprint for "
+ "sample key %d: %s\n",
+ __FILE__, __LINE__, idx, gpg_strerror (err));
+ exit (1);
+ }
+
+ if (strcmp (string, sample_keys[idx].fpr_md5))
+ {
+ fprintf (stderr, "%s:%d: fingerprint mismatch for "
+ "sample key %d\n",
+ __FILE__, __LINE__, idx);
+ fprintf (stderr, "want: %s\n got: %s\n",
+ sample_keys[idx].fpr_md5, string);
+ exit (1);
+ }
+ xfree (string);
+
+ err = ssh_get_fingerprint_string (key, GCRY_MD_SHA256, &string);
if (err)
{
fprintf (stderr, "%s:%d: error getting fingerprint for "
@@ -297,16 +372,18 @@ main (int argc, char **argv)
exit (1);
}
- if (strcmp (string, sample_keys[idx].fpr))
+ if (strcmp (string, sample_keys[idx].fpr_sha256))
{
fprintf (stderr, "%s:%d: fingerprint mismatch for "
"sample key %d\n",
__FILE__, __LINE__, idx);
fprintf (stderr, "want: %s\n got: %s\n",
- sample_keys[idx].fpr, string);
+ sample_keys[idx].fpr_sha256, string);
exit (1);
}
xfree (string);
+
+ gcry_sexp_release (key);
}
}
diff --git a/common/t-stringhelp.c b/common/t-stringhelp.c
index 189fed1..7c6fb80 100644
--- a/common/t-stringhelp.c
+++ b/common/t-stringhelp.c
@@ -761,6 +761,81 @@ test_split_fields (void)
}
+static void
+test_split_fields_colon (void)
+{
+ struct {
+ const char *s;
+ int nfields;
+ const char *fields_expected[10];
+ } tv[] = {
+ {
+ "a:bc:cde:fghi:jklmn: foo ", 6,
+ { "a", "bc", "cde", "fghi", "jklmn", " foo ", NULL }
+ },
+ {
+ " a:bc: def ", 2,
+ { " a", "bc", NULL }
+ },
+ {
+ " a:bc :def ", 3,
+ { " a", "bc ", "def ", NULL }
+ },
+ {
+ " a:bc: def ", 4,
+ { " a", "bc", " def ", NULL }
+ },
+ {
+ "", 0,
+ { NULL }
+ }
+ };
+
+ int tidx;
+ char *fields[10];
+ int field_count_expected, nfields, field_count, i;
+ char *s2;
+
+ for (tidx = 0; tidx < DIM(tv); tidx++)
+ {
+ nfields = tv[tidx].nfields;
+ assert (nfields <= DIM (fields));
+
+ /* Count the fields. */
+ for (field_count_expected = 0;
+ tv[tidx].fields_expected[field_count_expected];
+ field_count_expected ++)
+ ;
+ if (field_count_expected > nfields)
+ field_count_expected = nfields;
+
+ /* We need to copy s since split_fields modifies in place. */
+ s2 = xstrdup (tv[tidx].s);
+ field_count = split_fields_colon (s2, fields, nfields);
+
+ if (field_count != field_count_expected)
+ {
+ printf ("%s: tidx %d: expected %d, got %d\n",
+ __func__, tidx, field_count_expected, field_count);
+ fail (tidx * 1000);
+ }
+ else
+ {
+ for (i = 0; i < field_count_expected; i ++)
+ if (strcmp (tv[tidx].fields_expected[i], fields[i]))
+ {
+ printf ("%s: tidx %d, field %d: expected '%s', got '%s'\n",
+ __func__,
+ tidx, i, tv[tidx].fields_expected[i], fields[i]);
+ fail (tidx * 1000 + i + 1);
+ }
+ }
+
+ xfree (s2);
+ }
+}
+
+
static char *
stresc (char *s)
{
@@ -996,6 +1071,7 @@ main (int argc, char **argv)
test_strsplit ();
test_strtokenize ();
test_split_fields ();
+ test_split_fields_colon ();
test_compare_version_strings ();
test_format_text ();
diff --git a/common/util.h b/common/util.h
index c0aa57a..c6d19c6 100644
--- a/common/util.h
+++ b/common/util.h
@@ -235,6 +235,7 @@ const char *default_homedir (void);
void gnupg_set_homedir (const char *newdir);
const char *gnupg_homedir (void);
int gnupg_default_homedir_p (void);
+const char *gnupg_daemon_rootdir (void);
const char *gnupg_socketdir (void);
const char *gnupg_sysconfdir (void);
const char *gnupg_bindir (void);
@@ -302,6 +303,7 @@ 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_utf8_string (estream_t stream, const char *p);
void print_hexstring (FILE *fp, const void *buffer, size_t length,
int reserved);
char *try_make_printable_string (const void *p, size_t n, int delim);
diff --git a/configure.ac b/configure.ac
index 9395fb8..764a62d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -28,7 +28,7 @@ min_automake_version="1.14"
m4_define([mym4_package],[gnupg])
m4_define([mym4_major], [2])
m4_define([mym4_minor], [1])
-m4_define([mym4_micro], [21])
+m4_define([mym4_micro], [22])
# 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
@@ -486,7 +486,8 @@ AH_BOTTOM([
#define SAFE_VERSION_DOT '.'
#define SAFE_VERSION_DASH '-'
-/* Some global constants. */
+/* Some global constants.
+ * Note that the homedir must not end in a slash. */
#ifdef HAVE_DOSISH_SYSTEM
# ifdef HAVE_DRIVE_LETTERS
# define GNUPG_DEFAULT_HOMEDIR "c:/gnupg"
@@ -605,6 +606,8 @@ AC_PROG_RANLIB
AC_CHECK_TOOL(AR, ar, :)
AC_PATH_PROG(PERL,"perl")
AC_CHECK_TOOL(WINDRES, windres, :)
+AC_PATH_PROG(YAT2M, "yat2m", "./yat2m" )
+AC_ARG_VAR(YAT2M, [tool to convert texi to man pages])
AC_ISC_POSIX
AC_SYS_LARGEFILE
GNUPG_CHECK_USTAR
diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am
index 34f2c5d..b404165 100644
--- a/dirmngr/Makefile.am
+++ b/dirmngr/Makefile.am
@@ -143,7 +143,7 @@ endif
t_http_SOURCES = $(t_common_src) t-http.c http.c dns-stuff.c http-common.c
t_http_CFLAGS = -DWITHOUT_NPTH=1 $(USE_C99_CFLAGS) \
$(LIBGCRYPT_CFLAGS) $(NTBTLS_CFLAGS) $(LIBGNUTLS_CFLAGS) \
- $(GPG_ERROR_CFLAGS) $(KSBA_CFLAGS)
+ $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS) $(KSBA_CFLAGS)
t_http_LDADD = $(t_common_ldadd) \
$(NTBTLS_LIBS) $(KSBA_LIBS) $(LIBGNUTLS_LIBS) $(DNSLIBS)
@@ -152,11 +152,13 @@ t_ldap_parse_uri_SOURCES = \
http.c http-common.c dns-stuff.c \
$(ldap_url) $(t_common_src)
t_ldap_parse_uri_CFLAGS = -DWITHOUT_NPTH=1 $(USE_C99_CFLAGS) \
- $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS)
+ $(LIBGCRYPT_CFLAGS) \
+ $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS)
t_ldap_parse_uri_LDADD = $(ldaplibs) $(t_common_ldadd) $(DNSLIBS)
t_dns_stuff_CFLAGS = -DWITHOUT_NPTH=1 $(USE_C99_CFLAGS) \
- $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS)
+ $(LIBGCRYPT_CFLAGS) \
+ $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS)
t_dns_stuff_SOURCES = $(t_common_src) t-dns-stuff.c dns-stuff.c
t_dns_stuff_LDADD = $(t_common_ldadd) $(DNSLIBS)
diff --git a/dirmngr/dirmngr-client.c b/dirmngr/dirmngr-client.c
index 4dc64bf..53b405e 100644
--- a/dirmngr/dirmngr-client.c
+++ b/dirmngr/dirmngr-client.c
@@ -80,7 +80,7 @@ static ARGPARSE_OPTS opts[] = {
{ 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 }
+ ARGPARSE_end ()
};
diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
index 8393e0b..0d133c6 100644
--- a/dirmngr/dirmngr.c
+++ b/dirmngr/dirmngr.c
@@ -147,6 +147,8 @@ enum cmd_and_opt_values {
oStandardResolver,
oRecursiveResolver,
oResolverTimeout,
+ oConnectTimeout,
+ oConnectQuickTimeout,
aTest
};
@@ -250,6 +252,8 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oStandardResolver, "standard-resolver", "@"),
ARGPARSE_s_n (oRecursiveResolver, "recursive-resolver", "@"),
ARGPARSE_s_i (oResolverTimeout, "resolver-timeout", "@"),
+ ARGPARSE_s_i (oConnectTimeout, "connect-timeout", "@"),
+ ARGPARSE_s_i (oConnectQuickTimeout, "connect-quick-timeout", "@"),
ARGPARSE_group (302,N_("@\n(See the \"info\" manual for a complete listing "
"of all commands and options)\n")),
@@ -277,6 +281,9 @@ static struct debug_flags_s debug_flags [] =
#define DEFAULT_MAX_REPLIES 10
#define DEFAULT_LDAP_TIMEOUT 100 /* arbitrary large timeout */
+#define DEFAULT_CONNECT_TIMEOUT (15*1000) /* 15 seconds */
+#define DEFAULT_CONNECT_QUICK_TIMEOUT ( 2*1000) /* 2 seconds */
+
/* For the cleanup handler we need to keep track of the socket's name. */
static const char *socket_name;
/* If the socket has been redirected, this is the name of the
@@ -327,8 +334,9 @@ static int network_activity_seen;
static strlist_t hkp_cacert_filenames;
-/* The timer tick used for housekeeping stuff. */
-#define TIMERTICK_INTERVAL (60)
+/* The timer tick used for housekeeping stuff. The second constant is used when a shutdown is pending. */
+#define TIMERTICK_INTERVAL (60)
+#define TIMERTICK_INTERVAL_SHUTDOWN (4)
/* How oft to run the housekeeping. */
#define HOUSEKEEPING_INTERVAL (600)
@@ -524,7 +532,17 @@ dirmngr_use_tor (void)
{
if (tor_mode == TOR_MODE_AUTO)
{
- /* FIXME: Figure out whether Tor is running. */
+ /* Figure out whether Tor is running. */
+ assuan_fd_t sock;
+
+ sock = assuan_sock_connect_byname (NULL, 0, 0, NULL, ASSUAN_SOCK_TOR);
+ if (sock == ASSUAN_INVALID_FD)
+ tor_mode = TOR_MODE_NO;
+ else
+ {
+ tor_mode = TOR_MODE_YES;
+ assuan_sock_close (sock);
+ }
}
if (tor_mode == TOR_MODE_FORCE)
@@ -602,6 +620,8 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
disable_check_own_socket = 0;
enable_standard_resolver (0);
set_dns_timeout (0);
+ opt.connect_timeout = 0;
+ opt.connect_quick_timeout = 0;
return 1;
}
@@ -703,6 +723,14 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
set_dns_timeout (pargs->r.ret_int);
break;
+ case oConnectTimeout:
+ opt.connect_timeout = pargs->r.ret_ulong * 1000;
+ break;
+
+ case oConnectQuickTimeout:
+ opt.connect_quick_timeout = pargs->r.ret_ulong * 1000;
+ break;
+
default:
return 0; /* Not handled. */
}
@@ -716,6 +744,21 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
}
+/* This fucntion is called after option parsing to adjust some values
+ * and call option setup functions. */
+static void
+post_option_parsing (void)
+{
+ /* It would be too surpirsing if the quick timeout is larger than
+ * the standard value. */
+ if (opt.connect_quick_timeout > opt.connect_timeout)
+ opt.connect_quick_timeout = opt.connect_timeout;
+
+ set_debug ();
+ set_tor_mode ();
+}
+
+
#ifndef HAVE_W32_SYSTEM
static int
pid_suffix_callback (unsigned long *r_suffix)
@@ -844,6 +887,10 @@ main (int argc, char **argv)
/* Reset rereadable options to default values. */
parse_rereadable_options (NULL, 0);
+ /* Default TCP timeouts. */
+ opt.connect_timeout = DEFAULT_CONNECT_TIMEOUT;
+ opt.connect_quick_timeout = DEFAULT_CONNECT_QUICK_TIMEOUT;
+
/* LDAP defaults. */
opt.add_new_ldapservers = 0;
opt.ldaptimeout = DEFAULT_LDAP_TIMEOUT;
@@ -1031,8 +1078,7 @@ main (int argc, char **argv)
log_printf ("\n");
}
- set_debug ();
- set_tor_mode ();
+ post_option_parsing ();
/* Get LDAP server list from file. */
#if USE_LDAP
@@ -1316,13 +1362,18 @@ main (int argc, char **argv)
log_set_prefix (NULL, oldflags | GPGRT_LOG_RUN_DETACHED);
opt.running_detached = 1;
- if (chdir("/"))
+ }
+#endif
+
+ if (!nodetach )
+ {
+ if (gnupg_chdir (gnupg_daemon_rootdir ()))
{
- log_error ("chdir to / failed: %s\n", strerror (errno));
+ log_error ("chdir to '%s' failed: %s\n",
+ gnupg_daemon_rootdir (), strerror (errno));
dirmngr_exit (1);
}
}
-#endif
thread_init ();
cert_cache_init (hkp_cacert_filenames);
@@ -1513,6 +1564,7 @@ dirmngr_init_default_ctrl (ctrl_t ctrl)
if (opt.http_proxy)
ctrl->http_proxy = xstrdup (opt.http_proxy);
ctrl->http_no_crl = 1;
+ ctrl->timeout = opt.connect_timeout;
}
@@ -1774,8 +1826,7 @@ reread_configuration (void)
}
fclose (fp);
- set_debug ();
- set_tor_mode ();
+ post_option_parsing ();
}
@@ -1927,6 +1978,8 @@ time_for_housekeeping_p (time_t curtime)
static void
handle_tick (void)
{
+ struct stat statbuf;
+
if (time_for_housekeeping_p (gnupg_get_time ()))
{
npth_t thread;
@@ -1946,6 +1999,14 @@ handle_tick (void)
npth_attr_destroy (&tattr);
}
}
+
+ /* Check whether the homedir is still available. */
+ if (!shutdown_pending
+ && stat (gnupg_homedir (), &statbuf) && errno == ENOENT)
+ {
+ shutdown_pending = 1;
+ log_info ("homedir has been removed - shutting down\n");
+ }
}
@@ -2139,10 +2200,13 @@ handle_connections (assuan_fd_t listen_fd)
npth_clock_gettime (&curtime);
if (!(npth_timercmp (&curtime, &abstime, <)))
{
- /* Timeout. */
+ /* Timeout. When a shutdown is pending we use a shorter
+ * interval to handle the shutdown more quickly. */
handle_tick ();
npth_clock_gettime (&abstime);
- abstime.tv_sec += TIMERTICK_INTERVAL;
+ abstime.tv_sec += (shutdown_pending
+ ? TIMERTICK_INTERVAL_SHUTDOWN
+ : TIMERTICK_INTERVAL);
}
npth_timersub (&abstime, &curtime, &timeout);
diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h
index e10de09..1f660de 100644
--- a/dirmngr/dirmngr.h
+++ b/dirmngr/dirmngr.h
@@ -95,6 +95,10 @@ struct
int force; /* Force loading outdated CRLs. */
+
+ unsigned int connect_timeout; /* Timeout for connect. */
+ unsigned int connect_quick_timeout; /* Shorter timeout for connect. */
+
int disable_http; /* Do not use HTTP at all. */
int disable_ldap; /* Do not use LDAP at all. */
int disable_ipv4; /* Do not use legacy IP addresses. */
@@ -194,6 +198,8 @@ struct server_control_s
int audit_events; /* Send audit events to client. */
char *http_proxy; /* The used http_proxy or NULL. */
+ unsigned int timeout; /* Timeout for connect calls in ms. */
+
unsigned int http_no_crl:1; /* Do not check CRLs for https. */
};
@@ -223,6 +229,9 @@ int dirmngr_assuan_log_monitor (assuan_context_t ctx, unsigned int cat,
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_status_printf (ctrl_t ctrl, const char *keyword,
+ const char *format,
+ ...) GPGRT_ATTR_PRINTF(3,4);
gpg_error_t dirmngr_tick (ctrl_t ctrl);
/*-- http-ntbtls.c --*/
diff --git a/dirmngr/dirmngr_ldap.c b/dirmngr/dirmngr_ldap.c
index 836ced0..5a9ae97 100644
--- a/dirmngr/dirmngr_ldap.c
+++ b/dirmngr/dirmngr_ldap.c
@@ -150,7 +150,7 @@ static ARGPARSE_OPTS opts[] = {
{ oAttr, "attr", 2, N_("|STRING|return the attribute STRING")},
{ oOnlySearchTimeout, "only-search-timeout", 0, "@"},
{ oLogWithPID,"log-with-pid", 0, "@"},
- { 0, NULL, 0, NULL }
+ ARGPARSE_end ()
};
diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
index a6c14cd..7324aae 100644
--- a/dirmngr/dns-stuff.c
+++ b/dirmngr/dns-stuff.c
@@ -45,6 +45,9 @@
# endif
# include <netdb.h>
#endif
+#ifdef HAVE_STAT
+# include <sys/stat.h>
+#endif
#include <string.h>
#include <unistd.h>
@@ -111,6 +114,8 @@
#define DEFAULT_TIMEOUT 30
+#define RESOLV_CONF_NAME "/etc/resolv.conf"
+
/* Two flags to enable verbose and debug mode. */
static int opt_verbose;
static int opt_debug;
@@ -391,6 +396,39 @@ libdns_error_to_gpg_error (int serr)
#endif /*USE_LIBDNS*/
+/* Return true if resolve.conf changed since it was last loaded. */
+#ifdef USE_LIBDNS
+static int
+resolv_conf_changed_p (void)
+{
+#if defined(HAVE_W32_SYSTEM) || !defined(HAVE_STAT)
+ return 0;
+#else
+ static time_t last_mtime;
+ const char *fname = RESOLV_CONF_NAME;
+ struct stat statbuf;
+ int changed = 0;
+
+ if (stat (fname, &statbuf))
+ {
+ log_error ("stat'ing '%s' failed: %s\n",
+ fname, gpg_strerror (gpg_error_from_syserror ()));
+ last_mtime = 1; /* Force a "changed" result the next time stat
+ * works. */
+ }
+ else if (!last_mtime)
+ last_mtime = statbuf.st_mtime;
+ else if (last_mtime != statbuf.st_mtime)
+ {
+ changed = 1;
+ last_mtime = statbuf.st_mtime;
+ }
+
+ return changed;
+#endif
+}
+#endif /*USE_LIBDNS*/
+
#ifdef USE_LIBDNS
/* Initialize libdns. Returns 0 on success; prints a diagnostic and
* returns an error code on failure. */
@@ -496,7 +534,8 @@ libdns_init (void)
#else /* Unix */
const char *fname;
- fname = "/etc/resolv.conf";
+ fname = RESOLV_CONF_NAME;
+ resolv_conf_changed_p (); /* Reset timestamp. */
err = libdns_error_to_gpg_error
(dns_resconf_loadpath (ld.resolv_conf, fname));
if (err)
@@ -653,6 +692,14 @@ libdns_res_open (struct dns_resolver **r_res)
*r_res = NULL;
+ /* Force a reload if resolv.conf has changed. */
+ if (resolv_conf_changed_p ())
+ {
+ if (opt_debug)
+ log_debug ("dns: resolv.conf changed - forcing reload\n");
+ libdns_reinit_pending = 1;
+ }
+
if (libdns_reinit_pending)
{
libdns_reinit_pending = 0;
diff --git a/dirmngr/dns.c b/dirmngr/dns.c
index c660cf5..8e8b6db 100644
--- a/dirmngr/dns.c
+++ b/dirmngr/dns.c
@@ -205,8 +205,10 @@ typedef int socket_fd_t;
#ifndef HAVE_STATIC_ASSERT
#if DNS_GNUC_PREREQ(0,0,0) && !DNS_GNUC_PREREQ(4,6,0)
#define HAVE_STATIC_ASSERT 0 /* glibc doesn't check GCC version */
+#elif defined(static_assert)
+#define HAVE_STATIC_ASSERT 1
#else
-#define HAVE_STATIC_ASSERT (defined static_assert)
+#define HAVE_STATIC_ASSERT 0
#endif
#endif
@@ -380,7 +382,11 @@ const char *dns_strerror(int error) {
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef HAVE___ATOMIC_FETCH_ADD
-#define HAVE___ATOMIC_FETCH_ADD (defined __ATOMIC_RELAXED)
+#ifdef __ATOMIC_RELAXED
+#define HAVE___ATOMIC_FETCH_ADD 1
+#else
+#define HAVE___ATOMIC_FETCH_ADD 0
+#endif
#endif
#ifndef HAVE___ATOMIC_FETCH_SUB
@@ -787,7 +793,11 @@ DNS_NOTUSED static size_t dns_strnlcpy(char *dst, size_t lim, const char *src, s
} /* dns_strnlcpy() */
-#define DNS_HAVE_SOCKADDR_UN (defined AF_UNIX && !defined _WIN32)
+#if (defined AF_UNIX && !defined _WIN32)
+#define DNS_HAVE_SOCKADDR_UN 1
+#else
+#define DNS_HAVE_SOCKADDR_UN 0
+#endif
static size_t dns_af_len(int af) {
static const size_t table[AF_MAX] = {
@@ -7051,11 +7061,19 @@ static void dns_socketclose(int *fd, const struct dns_options *opts) {
#endif
#ifndef HAVE_SOCK_CLOEXEC
-#define HAVE_SOCK_CLOEXEC (defined SOCK_CLOEXEC)
+#ifdef SOCK_CLOEXEC
+#define HAVE_SOCK_CLOEXEC 1
+#else
+#define HAVE_SOCK_CLOEXEC 0
+#endif
#endif
#ifndef HAVE_SOCK_NONBLOCK
-#define HAVE_SOCK_NONBLOCK (defined SOCK_NONBLOCK)
+#ifdef SOCK_NONBLOCK
+#define HAVE_SOCK_NONBLOCK 1
+#else
+#define HAVE_SOCK_NONBLOCK 0
+#endif
#endif
#define DNS_SO_MAXTRY 7
@@ -7583,14 +7601,30 @@ int dns_so_check(struct dns_socket *so) {
retry:
switch (so->state) {
case DNS_SO_UDP_INIT:
- so->state++;
+ if (so->remote.ss_family != so->local.ss_family) {
+ /* Family mismatch. Reinitialize. */
+ if ((error = dns_so_closefd(so, &so->udp)))
+ goto error;
+ if ((error = dns_so_closefd(so, &so->tcp)))
+ goto error;
+
+ /* If the user supplied an interface
+ statement, that is gone now. Sorry. */
+ memset(&so->local, 0, sizeof so->local);
+ so->local.ss_family = so->remote.ss_family;
+
+ if (-1 == (so->udp = dns_socket((struct sockaddr *)&so->local, SOCK_DGRAM, &error)))
+ goto error;
+ }
+
+ so->state++; /* FALL THROUGH */
case DNS_SO_UDP_CONN:
error = dns_connect(so->udp, (struct sockaddr *)&so->remote, dns_sa_len(&so->remote));
dns_trace_sys_connect(so->trace, so->udp, SOCK_DGRAM, (struct sockaddr *)&so->remote, error);
if (error)
goto error;
- so->state++;
+ so->state++; /* FALL THROUGH */
case DNS_SO_UDP_SEND:
n = dns_send(so->udp, (void *)so->query->data, so->query->end, 0, &error);
dns_trace_sys_send(so->trace, so->udp, SOCK_DGRAM, so->query->data, n, error);
@@ -7600,7 +7634,7 @@ retry:
so->stat.udp.sent.bytes += n;
so->stat.udp.sent.count++;
- so->state++;
+ so->state++; /* FALL THROUGH */
case DNS_SO_UDP_RECV:
n = dns_recv(so->udp, (void *)so->answer->data, so->answer->size, 0, &error);
dns_trace_sys_recv(so->trace, so->udp, SOCK_DGRAM, so->answer->data, n, error);
@@ -7614,13 +7648,26 @@ retry:
if ((error = dns_so_verify(so, so->answer)))
goto trash;
- so->state++;
+ so->state++; /* FALL THROUGH */
case DNS_SO_UDP_DONE:
if (!dns_header(so->answer)->tc || so->type == SOCK_DGRAM)
return 0;
- so->state++;
+ so->state++; /* FALL THROUGH */
case DNS_SO_TCP_INIT:
+ if (so->remote.ss_family != so->local.ss_family) {
+ /* Family mismatch. Reinitialize. */
+ if ((error = dns_so_closefd(so, &so->udp)))
+ goto error;
+ if ((error = dns_so_closefd(so, &so->tcp)))
+ goto error;
+
+ /* If the user supplied an interface
+ statement, that is gone now. Sorry. */
+ memset(&so->local, 0, sizeof so->local);
+ so->local.ss_family = so->remote.ss_family;
+ }
+
if (dns_so_tcp_keep(so)) {
so->state = DNS_SO_TCP_SEND;
@@ -7633,24 +7680,24 @@ retry:
if (-1 == (so->tcp = dns_socket((struct sockaddr *)&so->local, SOCK_STREAM, &error)))
goto error;
- so->state++;
+ so->state++; /* FALL THROUGH */
case DNS_SO_TCP_CONN:
error = dns_connect(so->tcp, (struct sockaddr *)&so->remote, dns_sa_len(&so->remote));
dns_trace_sys_connect(so->trace, so->tcp, SOCK_STREAM, (struct sockaddr *)&so->remote, error);
if (error && error != DNS_EISCONN)
goto error;
- so->state++;
+ so->state++; /* FALL THROUGH */
case DNS_SO_TCP_SEND:
if ((error = dns_so_tcp_send(so)))
goto error;
- so->state++;
+ so->state++; /* FALL THROUGH */
case DNS_SO_TCP_RECV:
if ((error = dns_so_tcp_recv(so)))
goto error;
- so->state++;
+ so->state++; /* FALL THROUGH */
case DNS_SO_TCP_DONE:
/* close unless DNS_RESCONF_TCP_ONLY (see dns_res_tcp2type) */
if (so->type != SOCK_STREAM) {
@@ -7669,7 +7716,7 @@ retry:
if (-1 == (so->tcp = dns_socket((struct sockaddr *)&so->local, SOCK_STREAM, &error)))
goto error;
- so->state++;
+ so->state++; /* FALL THROUGH */
case DNS_SO_SOCKS_CONN: {
unsigned char method;
@@ -7697,13 +7744,13 @@ retry:
buffer[2] = method;
so->state++;
- }
+ } /* FALL THROUGH */
case DNS_SO_SOCKS_HELLO_SEND:
if ((error = dns_so_tcp_send(so)))
goto error;
dns_so_tcp_recv_expect(so, 2);
- so->state++;
+ so->state++; /* FALL THROUGH */
case DNS_SO_SOCKS_HELLO_RECV: {
unsigned char method;
@@ -7751,7 +7798,7 @@ retry:
}
so->state++;
- }
+ } /* FALL THROUGH */
case DNS_SO_SOCKS_AUTH_SEND:
if ((error = dns_so_tcp_send(so)))
goto error;
@@ -7759,7 +7806,7 @@ retry:
/* Skip the two length octets, and receive two octets. */
dns_so_tcp_recv_expect(so, 2);
- so->state++;
+ so->state++; /* FALL THROUGH */
case DNS_SO_SOCKS_AUTH_RECV:
if ((error = dns_so_tcp_recv(so)))
goto error;
@@ -7776,7 +7823,7 @@ retry:
goto error;
}
- so->state++;
+ so->state++; /* FALL THROUGH */
case DNS_SO_SOCKS_REQUEST_PREPARE:
/* Send request details (rfc-1928, 4). */
buffer = dns_so_tcp_send_buffer(so, so->remote.ss_family == AF_INET6 ? 22 : 10);
@@ -7797,7 +7844,7 @@ retry:
memcpy (buffer+8, &addr_in->sin_port, 2); /* DST.PORT */
}
- so->state++;
+ so->state++; /* FALL THROUGH */
case DNS_SO_SOCKS_REQUEST_SEND:
if ((error = dns_so_tcp_send(so)))
goto error;
@@ -7805,7 +7852,7 @@ retry:
/* Expect ten octets. This is the length of the
* response assuming a IPv4 address is used. */
dns_so_tcp_recv_expect(so, 10);
- so->state++;
+ so->state++; /* FALL THROUGH */
case DNS_SO_SOCKS_REQUEST_RECV:
if ((error = dns_so_tcp_recv(so)))
goto error;
@@ -7863,12 +7910,12 @@ retry:
* the remaining bytes assuming an IPv6 address is
* used. */
dns_so_tcp_recv_expect(so, 12);
- so->state++;
+ so->state++; /* FALL THROUGH */
case DNS_SO_SOCKS_REQUEST_RECV_V6:
if ((error = dns_so_tcp_recv(so)))
goto error;
- so->state++;
+ so->state++; /* FALL THROUGH */
case DNS_SO_SOCKS_HANDSHAKE_DONE:
/* We have not way to store the actual address used by
* the server. Then again, we don't really care. */
@@ -8072,6 +8119,8 @@ enum dns_res_state {
DNS_R_RESOLV1_NS, /* Epilog: Inspect answer */
DNS_R_FOREACH_A,
DNS_R_QUERY_A,
+ DNS_R_FOREACH_AAAA,
+ DNS_R_QUERY_AAAA,
DNS_R_CNAME0_A,
DNS_R_CNAME1_A,
@@ -8494,7 +8543,7 @@ exec:
switch (F->state) {
case DNS_R_INIT:
- F->state++;
+ F->state++; /* FALL THROUGH */
case DNS_R_GLUE:
if (R->sp == 0)
dgoto(R->sp, DNS_R_SWITCH);
@@ -8608,17 +8657,17 @@ exec:
} else if (error)
goto error;
- F->state++;
+ F->state++; /* FALL THROUGH */
case DNS_R_SUBMIT:
if ((error = R->cache->submit(F->query, R->cache)))
goto error;
- F->state++;
+ F->state++; /* FALL THROUGH */
case DNS_R_CHECK:
if ((error = R->cache->check(R->cache)))
goto error;
- F->state++;
+ F->state++; /* FALL THROUGH */
case DNS_R_FETCH:
error = 0;
@@ -8643,7 +8692,7 @@ exec:
R->search = 0;
- F->state++;
+ F->state++; /* FALL THROUGH */
case DNS_R_SEARCH:
/*
* XXX: We probably should only apply the domain search
@@ -8655,12 +8704,12 @@ exec:
if ((error = dns_q_make2(&F->query, u.name, len, R->qtype, R->qclass, F->qflags)))
goto error;
- F->state++;
+ F->state++; /* FALL THROUGH */
case DNS_R_HINTS:
if (!dns_p_setptr(&F->hints, dns_hints_query(R->hints, F->query, &error)))
goto error;
- F->state++;
+ F->state++; /* FALL THROUGH */
case DNS_R_ITERATE:
dns_rr_i_init(&F->hints_i, F->hints);
@@ -8669,7 +8718,7 @@ exec:
F->hints_i.sort = &dns_res_nameserv_cmp;
F->hints_i.args[0] = F->hints->end;
- F->state++;
+ F->state++; /* FALL THROUGH */
case DNS_R_FOREACH_NS:
dns_rr_i_save(&F->hints_i);
@@ -8731,8 +8780,22 @@ exec:
F->hints_j.section = DNS_S_ALL & ~DNS_S_QD;
if (!dns_rr_grep(&rr, 1, &F->hints_j, F->hints, &error)) {
- if (!dns_rr_i_count(&F->hints_j))
+ if (!dns_rr_i_count(&F->hints_j)) {
+ /* Check if we have in fact servers
+ with an IPv6 address. */
+ dns_rr_i_init(&F->hints_j, F->hints);
+ F->hints_j.name = u.ns.host;
+ F->hints_j.type = DNS_T_AAAA;
+ F->hints_j.section = DNS_S_ALL & ~DNS_S_QD;
+ if (dns_rr_grep(&rr, 1, &F->hints_j, F->hints, &error)) {
+ /* We do. Reinitialize
+ iterator and handle it. */
+ dns_rr_i_init(&F->hints_j, F->hints);
+ dgoto(R->sp, DNS_R_FOREACH_AAAA);
+ }
+
dgoto(R->sp, DNS_R_RESOLV0_NS);
+ }
dgoto(R->sp, DNS_R_FOREACH_NS);
}
@@ -8761,7 +8824,7 @@ exec:
goto error;
F->state++;
- }
+ } /* FALL THROUGH */
case DNS_R_QUERY_A:
if (dns_so_elapsed(&R->so) >= dns_resconf_timeout(R->resconf))
dgoto(R->sp, DNS_R_FOREACH_A);
@@ -8833,6 +8896,139 @@ exec:
/* XXX: Should we copy F->answer to R->nodata? */
dgoto(R->sp, DNS_R_FOREACH_A);
+ case DNS_R_FOREACH_AAAA: {
+ struct dns_aaaa aaaa;
+ struct sockaddr_in6 sin6;
+
+ /*
+ * NOTE: Iterator initialized in DNS_R_FOREACH_NS because
+ * this state is re-entrant, but we need to reset
+ * .name to a valid pointer each time.
+ */
+ if ((error = dns_ns_parse(&u.ns, &F->hints_ns, F->hints)))
+ goto error;
+
+ F->hints_j.name = u.ns.host;
+ F->hints_j.type = DNS_T_AAAA;
+ F->hints_j.section = DNS_S_ALL & ~DNS_S_QD;
+
+ if (!dns_rr_grep(&rr, 1, &F->hints_j, F->hints, &error)) {
+ if (!dns_rr_i_count(&F->hints_j)) {
+ /* Check if we have in fact servers
+ with an IPv4 address. */
+ dns_rr_i_init(&F->hints_j, F->hints);
+ F->hints_j.name = u.ns.host;
+ F->hints_j.type = DNS_T_A;
+ F->hints_j.section = DNS_S_ALL & ~DNS_S_QD;
+ if (dns_rr_grep(&rr, 1, &F->hints_j, F->hints, &error)) {
+ /* We do. Reinitialize
+ iterator and handle it. */
+ dns_rr_i_init(&F->hints_j, F->hints);
+ dgoto(R->sp, DNS_R_FOREACH_A);
+ }
+
+ dgoto(R->sp, DNS_R_RESOLV0_NS);
+ }
+
+ dgoto(R->sp, DNS_R_FOREACH_NS);
+ }
+
+ if ((error = dns_aaaa_parse(&aaaa, &rr, F->hints)))
+ goto error;
+
+ memset(&sin6, '\0', sizeof sin6); /* NB: silence valgrind */
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_addr = aaaa.addr;
+ if (R->sp == 0)
+ sin6.sin6_port = dns_hints_port(R->hints, AF_INET, &sin6.sin6_addr);
+ else
+ sin6.sin6_port = htons(53);
+
+ if (DNS_DEBUG) {
+ char addr[INET6_ADDRSTRLEN + 1];
+ dns_aaaa_print(addr, sizeof addr, &aaaa);
+ dns_header(F->query)->qid = dns_so_mkqid(&R->so);
+ DNS_SHOW(F->query, "ASKING: %s/%s @ DEPTH: %u)", u.ns.host, addr, R->sp);
+ }
+
+ dns_trace_setcname(R->trace, u.ns.host, (struct sockaddr *)&sin6);
+
+ if ((error = dns_so_submit(&R->so, F->query, (struct sockaddr *)&sin6)))
+ goto error;
+
+ F->state++;
+ } /* FALL THROUGH */
+ case DNS_R_QUERY_AAAA:
+ if (dns_so_elapsed(&R->so) >= dns_resconf_timeout(R->resconf))
+ dgoto(R->sp, DNS_R_FOREACH_AAAA);
+
+ if ((error = dns_so_check(&R->so)))
+ goto error;
+
+ if (!dns_p_setptr(&F->answer, dns_so_fetch(&R->so, &error)))
+ goto error;
+
+ if (DNS_DEBUG) {
+ DNS_SHOW(F->answer, "ANSWER @ DEPTH: %u)", R->sp);
+ }
+
+ if (dns_p_rcode(F->answer) == DNS_RC_FORMERR ||
+ dns_p_rcode(F->answer) == DNS_RC_NOTIMP ||
+ dns_p_rcode(F->answer) == DNS_RC_BADVERS) {
+ /* Temporarily disable EDNS0 and try again. */
+ if (F->qflags & DNS_Q_EDNS0) {
+ F->qflags &= ~DNS_Q_EDNS0;
+ if ((error = dns_q_remake(&F->query, F->qflags)))
+ goto error;
+
+ dgoto(R->sp, DNS_R_FOREACH_AAAA);
+ }
+ }
+
+ if ((error = dns_rr_parse(&rr, 12, F->query)))
+ goto error;
+
+ if (!(len = dns_d_expand(u.name, sizeof u.name, rr.dn.p, F->query, &error)))
+ goto error;
+ else if (len >= sizeof u.name)
+ goto toolong;
+
+ dns_rr_foreach(&rr, F->answer, .section = DNS_S_AN, .name = u.name, .type = rr.type) {
+ dgoto(R->sp, DNS_R_FINISH); /* Found */
+ }
+
+ dns_rr_foreach(&rr, F->answer, .section = DNS_S_AN, .name = u.name, .type = DNS_T_CNAME) {
+ F->ans_cname = rr;
+
+ dgoto(R->sp, DNS_R_CNAME0_A);
+ }
+
+ /*
+ * XXX: The condition here should probably check whether
+ * R->sp == 0, because DNS_R_SEARCH runs regardless of
+ * options.recurse. See DNS_R_BIND.
+ */
+ if (!R->resconf->options.recurse) {
+ /* Make first answer our tentative answer */
+ if (!R->nodata)
+ dns_p_movptr(&R->nodata, &F->answer);
+
+ dgoto(R->sp, DNS_R_SEARCH);
+ }
+
+ dns_rr_foreach(&rr, F->answer, .section = DNS_S_NS, .type = DNS_T_NS) {
+ dns_p_movptr(&F->hints, &F->answer);
+
+ dgoto(R->sp, DNS_R_ITERATE);
+ }
+
+ /* XXX: Should this go further up? */
+ if (dns_header(F->answer)->aa)
+ dgoto(R->sp, DNS_R_FINISH);
+
+ /* XXX: Should we copy F->answer to R->nodata? */
+
+ dgoto(R->sp, DNS_R_FOREACH_AAAA);
case DNS_R_CNAME0_A:
if (&F[1] >= endof(R->stack))
dgoto(R->sp, DNS_R_FINISH);
@@ -8864,7 +9060,7 @@ exec:
dns_rr_i_init(&R->smart, F->answer);
- F->state++;
+ F->state++; /* FALL THROUGH */
case DNS_R_SMART0_A:
if (&F[1] >= endof(R->stack))
dgoto(R->sp, DNS_R_DONE);
@@ -9549,12 +9745,12 @@ exec:
switch (ai->state) {
case DNS_AI_S_INIT:
- ai->state++;
+ ai->state++; /* FALL THROUGH */
case DNS_AI_S_NEXTAF:
if (!dns_ai_nextaf(ai))
dns_ai_goto(DNS_AI_S_DONE);
- ai->state++;
+ ai->state++; /* FALL THROUGH */
case DNS_AI_S_NUMERIC:
if (1 == dns_inet_pton(AF_INET, ai->qname, &any.a)) {
if (ai->af.atype == AF_INET) {
@@ -9577,19 +9773,19 @@ exec:
if (ai->hints.ai_flags & AI_NUMERICHOST)
dns_ai_goto(DNS_AI_S_NEXTAF);
- ai->state++;
+ ai->state++; /* FALL THROUGH */
case DNS_AI_S_SUBMIT:
assert(ai->res);
if ((error = dns_res_submit(ai->res, ai->qname, dns_ai_qtype(ai), DNS_C_IN)))
return error;
- ai->state++;
+ ai->state++; /* FALL THROUGH */
case DNS_AI_S_CHECK:
if ((error = dns_res_check(ai->res)))
return error;
- ai->state++;
+ ai->state++; /* FALL THROUGH */
case DNS_AI_S_FETCH:
if (!(ans = dns_res_fetch_and_study(ai->res, &error)))
return error;
@@ -9612,7 +9808,7 @@ exec:
ai->i.type = dns_ai_qtype(ai);
ai->i.sort = &dns_rr_i_order;
- ai->state++;
+ ai->state++; /* FALL THROUGH */
case DNS_AI_S_FOREACH_I:
if (!dns_rr_grep(&rr, 1, &ai->i, ai->answer, &error))
dns_ai_goto(DNS_AI_S_NEXTAF);
@@ -9646,11 +9842,11 @@ exec:
break;
} /* switch() */
- ai->state++;
+ ai->state++; /* FALL THROUGH */
case DNS_AI_S_INIT_G:
ai->g_depth = 0;
- ai->state++;
+ ai->state++; /* FALL THROUGH */
case DNS_AI_S_ITERATE_G:
dns_strlcpy(ai->g_cname, ai->cname, sizeof ai->g_cname);
dns_rr_i_init(&ai->g, ai->glue);
@@ -9658,7 +9854,7 @@ exec:
ai->g.name = ai->g_cname;
ai->g.type = ai->af.qtype;
- ai->state++;
+ ai->state++; /* FALL THROUGH */
case DNS_AI_S_FOREACH_G:
if (!dns_rr_grep(&rr, 1, &ai->g, ai->glue, &error)) {
if (dns_rr_i_count(&ai->g) > 0)
@@ -9682,12 +9878,12 @@ exec:
if ((error = dns_res_submit(ai->res, ai->g.name, ai->g.type, DNS_C_IN)))
return error;
- ai->state++;
+ ai->state++; /* FALL THROUGH */
case DNS_AI_S_CHECK_G:
if ((error = dns_res_check(ai->res)))
return error;
- ai->state++;
+ ai->state++; /* FALL THROUGH */
case DNS_AI_S_FETCH_G:
if (!(ans = dns_res_fetch_and_study(ai->res, &error)))
return error;
diff --git a/dirmngr/http.c b/dirmngr/http.c
index f461e5d..0bedba0 100644
--- a/dirmngr/http.c
+++ b/dirmngr/http.c
@@ -70,6 +70,7 @@
# include <sys/socket.h>
# include <sys/time.h>
# include <time.h>
+# include <fcntl.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <netdb.h>
@@ -153,13 +154,14 @@ static int insert_escapes (char *buffer, const char *string,
static uri_tuple_t parse_tuple (char *string);
static gpg_error_t send_request (http_t hd, const char *httphost,
const char *auth,const char *proxy,
- const char *srvtag,strlist_t headers);
+ const char *srvtag, unsigned int timeout,
+ strlist_t headers);
static char *build_rel_path (parsed_uri_t uri);
static gpg_error_t parse_response (http_t hd);
static gpg_error_t connect_server (const char *server, unsigned short port,
unsigned int flags, const char *srvtag,
- assuan_fd_t *r_sock);
+ unsigned int timeout, assuan_fd_t *r_sock);
static gpgrt_ssize_t read_server (assuan_fd_t sock, void *buffer, size_t size);
static gpg_error_t write_server (assuan_fd_t sock, const char *data, size_t length);
@@ -259,6 +261,9 @@ struct http_session_s
/* A per-session TLS verification callback. */
http_verify_cb_t verify_cb;
void *verify_cb_value;
+
+ /* The connect timeout */
+ unsigned int connect_timeout;
};
@@ -695,6 +700,7 @@ http_session_new (http_session_t *r_session,
sess->flags = flags;
sess->verify_cb = verify_cb;
sess->verify_cb_value = verify_cb_value;
+ sess->connect_timeout = 0;
#if HTTP_USE_NTBTLS
{
@@ -867,6 +873,15 @@ http_session_set_log_cb (http_session_t sess,
}
+/* Set the TIMEOUT in milliseconds for the connection's connect
+ * calls. Using 0 disables the timeout. */
+void
+http_session_set_timeout (http_session_t sess, unsigned int timeout)
+{
+ sess->connect_timeout = timeout;
+}
+
+
/* Start a HTTP retrieval and on success store at R_HD a context
@@ -898,7 +913,9 @@ http_open (http_t *r_hd, http_req_t reqtype, const char *url,
err = parse_uri (&hd->uri, url, 0, !!(flags & HTTP_FLAG_FORCE_TLS));
if (!err)
- err = send_request (hd, httphost, auth, proxy, srvtag, headers);
+ err = send_request (hd, httphost, auth, proxy, srvtag,
+ hd->session? hd->session->connect_timeout : 0,
+ headers);
if (err)
{
@@ -918,10 +935,10 @@ http_open (http_t *r_hd, http_req_t reqtype, const char *url,
/* 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. */
+ service tags and an estream interface. TIMEOUT is in milliseconds. */
gpg_error_t
http_raw_connect (http_t *r_hd, const char *server, unsigned short port,
- unsigned int flags, const char *srvtag)
+ unsigned int flags, const char *srvtag, unsigned int timeout)
{
gpg_error_t err = 0;
http_t hd;
@@ -938,6 +955,10 @@ http_raw_connect (http_t *r_hd, const char *server, unsigned short port,
log_error ("Tor support is not available\n");
return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
}
+ /* Non-blocking connects do not work with our Tor proxy because
+ * we can't continue the Socks protocol after the EINPROGRESS.
+ * Disable the timeout to use a blocking connect. */
+ timeout = 0;
}
/* Create the handle. */
@@ -952,7 +973,7 @@ http_raw_connect (http_t *r_hd, const char *server, unsigned short port,
{
assuan_fd_t sock;
- err = connect_server (server, port, hd->flags, srvtag, &sock);
+ err = connect_server (server, port, hd->flags, srvtag, timeout, &sock);
if (err)
{
xfree (hd);
@@ -1047,6 +1068,7 @@ http_wait_response (http_t hd)
{
gpg_error_t err;
cookie_t cookie;
+ int use_tls;
/* Make sure that we are in the data. */
http_start_data (hd);
@@ -1057,6 +1079,7 @@ http_wait_response (http_t hd)
if (!cookie)
return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
+ use_tls = cookie->use_tls;
es_fclose (hd->fp_write);
hd->fp_write = NULL;
/* The close has released the cookie and thus we better set it to NULL. */
@@ -1075,7 +1098,7 @@ http_wait_response (http_t hd)
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;
+ cookie->use_tls = use_tls;
hd->read_cookie = cookie;
hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
@@ -1202,14 +1225,16 @@ parse_uri (parsed_uri_t *ret_uri, const char *uri,
{
gpg_err_code_t ec;
- *ret_uri = xtrycalloc (1, sizeof **ret_uri + strlen (uri));
+ *ret_uri = xtrycalloc (1, sizeof **ret_uri + 2 * strlen (uri) + 1);
if (!*ret_uri)
return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
strcpy ((*ret_uri)->buffer, uri);
+ strcpy ((*ret_uri)->buffer + strlen (uri) + 1, uri);
+ (*ret_uri)->original = (*ret_uri)->buffer + strlen (uri) + 1;
ec = do_parse_uri (*ret_uri, 0, no_scheme_check, force_tls);
if (ec)
{
- xfree (*ret_uri);
+ http_release_parsed_uri (*ret_uri);
*ret_uri = NULL;
}
return gpg_err_make (default_errsource, ec);
@@ -1238,6 +1263,11 @@ http_release_parsed_uri (parsed_uri_t uri)
{
uri_tuple_t r, r2;
+ for (r = uri->params; r; r = r2)
+ {
+ r2 = r->next;
+ xfree (r);
+ }
for (r = uri->query; r; r = r2)
{
r2 = r->next;
@@ -1635,7 +1665,8 @@ is_hostname_port (const char *string)
*/
static gpg_error_t
send_request (http_t hd, const char *httphost, const char *auth,
- const char *proxy, const char *srvtag, strlist_t headers)
+ const char *proxy, const char *srvtag, unsigned int timeout,
+ strlist_t headers)
{
gpg_error_t err;
const char *server;
@@ -1645,6 +1676,9 @@ send_request (http_t hd, const char *httphost, const char *auth,
char *proxy_authstr = NULL;
char *authstr = NULL;
assuan_fd_t sock;
+#ifdef USE_TLS
+ int have_http_proxy = 0;
+#endif
if (hd->uri->use_tls && !hd->session)
{
@@ -1668,6 +1702,10 @@ send_request (http_t hd, const char *httphost, const char *auth,
log_error ("Tor support is not available\n");
return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
}
+ /* Non-blocking connects do not work with our Tor proxy because
+ * we can't continue the Socks protocol after the EINPROGRESS.
+ * Disable the timeout to use a blocking connect. */
+ timeout = 0;
}
server = *hd->uri->host ? hd->uri->host : "localhost";
@@ -1731,9 +1769,12 @@ send_request (http_t hd, const char *httphost, const char *auth,
if (err)
;
- else if (!strcmp (uri->scheme, "http") || !strcmp (uri->scheme, "socks4"))
- ;
- else if (!strcmp (uri->scheme, "socks5h"))
+#ifdef USE_TLS
+ else if (!strcmp (uri->scheme, "http"))
+ have_http_proxy = 1;
+#endif
+ else if (!strcmp (uri->scheme, "socks4")
+ || !strcmp (uri->scheme, "socks5h"))
err = gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
else
err = gpg_err_make (default_errsource, GPG_ERR_INV_URI);
@@ -1762,12 +1803,12 @@ send_request (http_t hd, const char *httphost, const char *auth,
err = connect_server (*uri->host ? uri->host : "localhost",
uri->port ? uri->port : 80,
- hd->flags, srvtag, &sock);
+ hd->flags, NULL, timeout, &sock);
http_release_parsed_uri (uri);
}
else
{
- err = connect_server (server, port, hd->flags, srvtag, &sock);
+ err = connect_server (server, port, hd->flags, srvtag, timeout, &sock);
}
if (err)
@@ -1782,6 +1823,94 @@ send_request (http_t hd, const char *httphost, const char *auth,
return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
}
+#if USE_TLS
+ if (have_http_proxy && hd->uri->use_tls)
+ {
+ int saved_flags;
+ cookie_t cookie;
+
+ /* Try to use the CONNECT method to proxy our TLS stream. */
+ request = es_bsprintf
+ ("CONNECT %s:%hu HTTP/1.0\r\nHost: %s:%hu\r\n%s",
+ httphost ? httphost : server,
+ port,
+ httphost ? httphost : server,
+ port,
+ proxy_authstr ? proxy_authstr : "");
+ xfree (proxy_authstr);
+ proxy_authstr = NULL;
+
+ if (! request)
+ return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+
+ if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
+ log_debug_with_string (request, "http.c:request:");
+
+ cookie = xtrycalloc (1, sizeof *cookie);
+ if (! cookie)
+ {
+ err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+ xfree (request);
+ return err;
+ }
+ cookie->sock = my_socket_ref (hd->sock);
+ hd->write_cookie = cookie;
+
+ 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);
+ xfree (request);
+ hd->write_cookie = NULL;
+ return err;
+ }
+ else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write))
+ err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+
+ xfree (request);
+ request = NULL;
+
+ /* Make sure http_wait_response doesn't close the stream. */
+ saved_flags = hd->flags;
+ hd->flags &= ~HTTP_FLAG_SHUTDOWN;
+
+ /* Get the response. */
+ err = http_wait_response (hd);
+
+ /* Restore flags, destroy stream. */
+ hd->flags = saved_flags;
+ es_fclose (hd->fp_read);
+ hd->fp_read = NULL;
+ hd->read_cookie = NULL;
+
+ /* Reset state. */
+ hd->in_data = 0;
+
+ if (err)
+ return err;
+
+ if (hd->status_code != 200)
+ {
+ request = es_bsprintf
+ ("CONNECT %s:%hu",
+ httphost ? httphost : server,
+ port);
+
+ log_error (_("error accessing '%s': http status %u\n"),
+ request ? request : "out of core",
+ http_get_status_code (hd));
+
+ xfree (request);
+ return gpg_error (GPG_ERR_NO_DATA);
+ }
+
+ /* We are done with the proxy, the code below will establish a
+ * TLS session and talk directly to the target server. */
+ http_proxy = NULL;
+ }
+#endif /* USE_TLS */
#if HTTP_USE_NTBTLS
if (hd->uri->use_tls)
@@ -2316,7 +2445,7 @@ parse_response (http_t hd)
if (!len)
return GPG_ERR_EOF;
- if ((hd->flags & HTTP_FLAG_LOG_RESP))
+ if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
log_debug_with_string (line, "http.c:response:\n");
}
while (!*line);
@@ -2361,7 +2490,7 @@ parse_response (http_t hd)
/* Trim line endings of empty lines. */
if ((*line == '\r' && line[1] == '\n') || *line == '\n')
*line = 0;
- if ((hd->flags & HTTP_FLAG_LOG_RESP))
+ if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
log_info ("http.c:RESP: '%.*s'\n",
(int)strlen(line)-(*line&&line[1]?2:0),line);
if (*line)
@@ -2526,13 +2655,162 @@ my_sock_new_for_addr (struct sockaddr_storage *addr, int type, int proto)
}
+/* Call WSAGetLastError and map it to a libgpg-error. */
+#ifdef HAVE_W32_SYSTEM
+static gpg_error_t
+my_wsagetlasterror (void)
+{
+ int wsaerr;
+ gpg_err_code_t ec;
+
+ wsaerr = WSAGetLastError ();
+ switch (wsaerr)
+ {
+ case WSAENOTSOCK: ec = GPG_ERR_EINVAL; break;
+ case WSAEWOULDBLOCK: ec = GPG_ERR_EAGAIN; break;
+ case ERROR_BROKEN_PIPE: ec = GPG_ERR_EPIPE; break;
+ case WSANOTINITIALISED: ec = GPG_ERR_ENOSYS; break;
+ case WSAENOBUFS: ec = GPG_ERR_ENOBUFS; break;
+ case WSAEMSGSIZE: ec = GPG_ERR_EMSGSIZE; break;
+ case WSAECONNREFUSED: ec = GPG_ERR_ECONNREFUSED; break;
+ case WSAEISCONN: ec = GPG_ERR_EISCONN; break;
+ case WSAEALREADY: ec = GPG_ERR_EALREADY; break;
+ case WSAETIMEDOUT: ec = GPG_ERR_ETIMEDOUT; break;
+ default: ec = GPG_ERR_EIO; break;
+ }
+
+ return gpg_err_make (default_errsource, ec);
+}
+#endif /*HAVE_W32_SYSTEM*/
+
+
+/* Connect SOCK and return GPG_ERR_ETIMEOUT if a connection could not
+ * be established within TIMEOUT milliseconds. 0 indicates the
+ * system's default timeout. The other args are the usual connect
+ * args. On success 0 is returned, on timeout GPG_ERR_ETIMEDOUT, and
+ * another error code for other errors. On timeout the caller needs
+ * to close the socket as soon as possible to stop an ongoing
+ * handshake.
+ *
+ * This implementation is for well-behaving systems; see Stevens,
+ * Network Programming, 2nd edition, Vol 1, 15.4. */
+static gpg_error_t
+connect_with_timeout (assuan_fd_t sock,
+ struct sockaddr *addr, int addrlen,
+ unsigned int timeout)
+{
+ gpg_error_t err;
+ int syserr;
+ socklen_t slen;
+ fd_set rset, wset;
+ struct timeval tval;
+ int n;
+
+#ifndef HAVE_W32_SYSTEM
+ int oflags;
+# define RESTORE_BLOCKING() do { \
+ fcntl (sock, F_SETFL, oflags); \
+ } while (0)
+#else /*HAVE_W32_SYSTEM*/
+# define RESTORE_BLOCKING() do { \
+ unsigned long along = 0; \
+ ioctlsocket (FD2INT (sock), FIONBIO, &along); \
+ } while (0)
+#endif /*HAVE_W32_SYSTEM*/
+
+
+ if (!timeout)
+ {
+ /* Shortcut. */
+ if (assuan_sock_connect (sock, addr, addrlen))
+ err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+ else
+ err = 0;
+ return err;
+ }
+
+ /* Switch the socket into non-blocking mode. */
+#ifdef HAVE_W32_SYSTEM
+ {
+ unsigned long along = 1;
+ if (ioctlsocket (FD2INT (sock), FIONBIO, &along))
+ return my_wsagetlasterror ();
+ }
+#else
+ oflags = fcntl (sock, F_GETFL, 0);
+ if (fcntl (sock, F_SETFL, oflags | O_NONBLOCK))
+ return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+#endif
+
+ /* Do the connect. */
+ if (!assuan_sock_connect (sock, addr, addrlen))
+ {
+ /* Immediate connect. Restore flags. */
+ RESTORE_BLOCKING ();
+ return 0; /* Success. */
+ }
+ err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+ if (gpg_err_code (err) != GPG_ERR_EINPROGRESS)
+ {
+ RESTORE_BLOCKING ();
+ return err;
+ }
+
+ FD_ZERO (&rset);
+ FD_SET (FD2INT (sock), &rset);
+ wset = rset;
+ tval.tv_sec = timeout / 1000;
+ tval.tv_usec = (timeout % 1000) * 1000;
+
+ n = my_select (FD2INT(sock)+1, &rset, &wset, NULL, &tval);
+ if (n < 0)
+ {
+ err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+ RESTORE_BLOCKING ();
+ return err;
+ }
+ if (!n)
+ {
+ /* Timeout: We do not restore the socket flags on timeout
+ * because the caller is expected to close the socket. */
+ return gpg_err_make (default_errsource, GPG_ERR_ETIMEDOUT);
+ }
+ if (!FD_ISSET (sock, &rset) && !FD_ISSET (sock, &wset))
+ {
+ /* select misbehaved. */
+ return gpg_err_make (default_errsource, GPG_ERR_SYSTEM_BUG);
+ }
+
+ slen = sizeof (syserr);
+ if (getsockopt (FD2INT(sock), SOL_SOCKET, SO_ERROR,
+ (void*)&syserr, &slen) < 0)
+ {
+ /* Assume that this is Solaris which returns the error in ERRNO. */
+ err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+ }
+ else if (syserr)
+ err = gpg_err_make (default_errsource, gpg_err_code_from_errno (syserr));
+ else
+ err = 0; /* Connected. */
+
+ RESTORE_BLOCKING ();
+
+ return err;
+
+#undef RESTORE_BLOCKING
+}
+
+
/* Actually connect to a server. On success 0 is returned and the
* file descriptor for the socket is stored at R_SOCK; on error an
- * error code is returned and ASSUAN_INVALID_FD is stored at
- * R_SOCK. */
+ * error code is returned and ASSUAN_INVALID_FD is stored at R_SOCK.
+ * TIMEOUT is the connect timeout in milliseconds. Note that the
+ * function tries to connect to all known addresses and the timeout is
+ * for each one. */
static gpg_error_t
connect_server (const char *server, unsigned short port,
- unsigned int flags, const char *srvtag, assuan_fd_t *r_sock)
+ unsigned int flags, const char *srvtag, unsigned int timeout,
+ assuan_fd_t *r_sock)
{
gpg_error_t err;
assuan_fd_t sock = ASSUAN_INVALID_FD;
@@ -2645,11 +2923,11 @@ connect_server (const char *server, unsigned short port,
}
anyhostaddr = 1;
- if (assuan_sock_connect (sock, (struct sockaddr *)ai->addr,
- ai->addrlen))
+ err = connect_with_timeout (sock, (struct sockaddr *)ai->addr,
+ ai->addrlen, timeout);
+ if (err)
{
- last_err = gpg_err_make (default_errsource,
- gpg_err_code_from_syserror ());
+ last_err = err;
}
else
{
@@ -3016,7 +3294,7 @@ gpg_error_t
http_verify_server_credentials (http_session_t sess)
{
#if HTTP_USE_GNUTLS
- static const char const errprefix[] = "TLS verification of peer failed";
+ static const char errprefix[] = "TLS verification of peer failed";
int rc;
unsigned int status;
const char *hostname;
diff --git a/dirmngr/http.h b/dirmngr/http.h
index 2609b9e..9fa462c 100644
--- a/dirmngr/http.h
+++ b/dirmngr/http.h
@@ -47,6 +47,7 @@ typedef struct uri_tuple_s *uri_tuple_t;
struct parsed_uri_s
{
/* All these pointers point into BUFFER; most stuff is not escaped. */
+ char *original; /* Unmodified copy of the parsed URI. */
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. */
@@ -124,6 +125,7 @@ void http_session_set_log_cb (http_session_t sess,
void (*cb)(http_session_t, gpg_error_t,
const char *,
const void **, size_t *));
+void http_session_set_timeout (http_session_t sess, unsigned int timeout);
gpg_error_t http_parse_uri (parsed_uri_t *ret_uri, const char *uri,
@@ -133,7 +135,8 @@ void http_release_parsed_uri (parsed_uri_t uri);
gpg_error_t http_raw_connect (http_t *r_hd,
const char *server, unsigned short port,
- unsigned int flags, const char *srvtag);
+ unsigned int flags, const char *srvtag,
+ unsigned int timeout);
gpg_error_t http_open (http_t *r_hd, http_req_t reqtype,
const char *url,
diff --git a/dirmngr/ks-action.c b/dirmngr/ks-action.c
index 1087bb5..857aab1 100644
--- a/dirmngr/ks-action.c
+++ b/dirmngr/ks-action.c
@@ -232,7 +232,10 @@ ks_action_get (ctrl_t ctrl, uri_item_t keyservers,
Need to think about a better strategy. */
for (uri = keyservers; !err && uri; uri = uri->next)
{
- int is_http = uri->parsed_uri->is_http;
+ int is_hkp_s = (strcmp (uri->parsed_uri->scheme, "hkp") == 0
+ || strcmp (uri->parsed_uri->scheme, "hkps") == 0);
+ int is_http_s = (strcmp (uri->parsed_uri->scheme, "http") == 0
+ || strcmp (uri->parsed_uri->scheme, "https") == 0);
int is_ldap = 0;
#if USE_LDAP
@@ -241,7 +244,7 @@ ks_action_get (ctrl_t ctrl, uri_item_t keyservers,
|| strcmp (uri->parsed_uri->scheme, "ldapi") == 0);
#endif
- if (is_http || is_ldap)
+ if (is_hkp_s || is_http_s || is_ldap)
{
any_server = 1;
for (sl = patterns; !err && sl; sl = sl->next)
@@ -251,9 +254,12 @@ ks_action_get (ctrl_t ctrl, uri_item_t keyservers,
err = ks_ldap_get (ctrl, uri->parsed_uri, sl->d, &infp);
else
#endif
- {
- err = ks_hkp_get (ctrl, uri->parsed_uri, sl->d, &infp);
- }
+ if (is_hkp_s)
+ err = ks_hkp_get (ctrl, uri->parsed_uri, sl->d, &infp);
+ else if (is_http_s)
+ err = ks_http_fetch (ctrl, uri->parsed_uri->original, &infp);
+ else
+ BUG ();
if (err)
{
diff --git a/dirmngr/ks-engine-finger.c b/dirmngr/ks-engine-finger.c
index f56a9ff..e53a0ee 100644
--- a/dirmngr/ks-engine-finger.c
+++ b/dirmngr/ks-engine-finger.c
@@ -86,7 +86,7 @@ ks_finger_fetch (ctrl_t ctrl, parsed_uri_t uri, estream_t *r_fp)
((dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR : 0)
| (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)
| (opt.disable_ipv6? HTTP_FLAG_IGNORE_IPv6 : 0)),
- NULL);
+ NULL, ctrl->timeout);
if (err)
{
xfree (name);
diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
index ddb8549..4a0b08f 100644
--- a/dirmngr/ks-engine-hkp.c
+++ b/dirmngr/ks-engine-hkp.c
@@ -67,6 +67,8 @@
/* Number of retries done for a dead host etc. */
#define SEND_REQUEST_RETRIES 3
+enum ks_protocol { KS_PROTOCOL_HKP, KS_PROTOCOL_HKPS, KS_PROTOCOL_MAX };
+
/* Objects used to maintain information about hosts. */
struct hostinfo_s;
typedef struct hostinfo_s *hostinfo_t;
@@ -74,9 +76,11 @@ 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 *pool; /* An array with indices into HOSTTABLE or NULL
+ if NAME is not a pool name. */
+ size_t pool_len; /* Length of POOL. */
+ size_t pool_size; /* Allocated size of POOL. */
+#define MAX_POOL_SIZE 128
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. */
@@ -84,12 +88,18 @@ struct hostinfo_s
unsigned int dead:1; /* Host is currently unresponsive. */
unsigned int iporname_valid:1; /* The field IPORNAME below is valid */
/* (but may be NULL) */
+ unsigned int did_a_lookup:1; /* Have we done an A lookup yet? */
+ unsigned int did_srv_lookup:2; /* One bit per protocol indicating
+ whether we already did a SRV
+ lookup. */
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 or NAME has a numerical IP address. */
char *iporname; /* Numeric IP address or name for printing. */
- unsigned short port; /* The port used by the host, 0 if unknown. */
+ unsigned short port[KS_PROTOCOL_MAX];
+ /* The port used by the host for all protocols, 0
+ if unknown. */
char name[1]; /* The hostname. */
};
@@ -118,6 +128,8 @@ create_new_hostinfo (const char *name)
return -1;
strcpy (hi->name, name);
hi->pool = NULL;
+ hi->pool_len = 0;
+ hi->pool_size = 0;
hi->poolidx = -1;
hi->lastused = (time_t)(-1);
hi->lastfail = (time_t)(-1);
@@ -125,11 +137,14 @@ create_new_hostinfo (const char *name)
hi->v6 = 0;
hi->onion = 0;
hi->dead = 0;
+ hi->did_a_lookup = 0;
+ hi->did_srv_lookup = 0;
hi->iporname_valid = 0;
hi->died_at = 0;
hi->cname = NULL;
hi->iporname = NULL;
- hi->port = 0;
+ hi->port[KS_PROTOCOL_HKP] = 0;
+ hi->port[KS_PROTOCOL_HKPS] = 0;
/* Add it to the hosttable. */
for (idx=0; idx < hosttable_size; idx++)
@@ -187,24 +202,24 @@ sort_hostpool (const void *xa, const void *xb)
}
-/* Return true if the host with the hosttable index TBLIDX is in POOL. */
+/* Return true if the host with the hosttable index TBLIDX is in HI->pool. */
static int
-host_in_pool_p (int *pool, int tblidx)
+host_in_pool_p (hostinfo_t hi, int tblidx)
{
int i, pidx;
- for (i=0; (pidx = pool[i]) != -1; i++)
+ for (i = 0; i < hi->pool_len && (pidx = hi->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
+/* Select a random host. Consult HI->pool which indices into the global
+ hosttable. Returns index into HI->pool or -1 if no host could be
selected. */
static int
-select_random_host (int *table)
+select_random_host (hostinfo_t hi)
{
int *tbl;
size_t tblsize;
@@ -212,7 +227,9 @@ select_random_host (int *table)
/* 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++)
+ for (idx = 0, tblsize = 0;
+ idx < hi->pool_len && (pidx = hi->pool[idx]) != -1;
+ idx++)
if (hosttable[pidx] && !hosttable[pidx]->dead)
tblsize++;
if (!tblsize)
@@ -221,7 +238,9 @@ select_random_host (int *table)
tbl = xtrymalloc (tblsize * sizeof *tbl);
if (!tbl)
return -1;
- for (idx=0, tblsize=0; (pidx = table[idx]) != -1; idx++)
+ for (idx = 0, tblsize = 0;
+ idx < hi->pool_len && (pidx = hi->pool[idx]) != -1;
+ idx++)
if (hosttable[pidx] && !hosttable[pidx]->dead)
tbl[tblsize++] = pidx;
@@ -255,7 +274,7 @@ arecords_is_pool (dns_addrinfo_t aibuf)
}
-/* Print a warninng iff Tor is not running but Tor has been requested.
+/* Print a warning iff Tor is not running but Tor has been requested.
* Also return true if it is not running. */
static int
tor_not_running_p (ctrl_t ctrl)
@@ -281,20 +300,22 @@ tor_not_running_p (ctrl_t ctrl)
/* Add the host AI under the NAME into the HOSTTABLE. If PORT is not
- zero, it specifies which port to use to talk to the host. If NAME
- specifies a pool (as indicated by IS_POOL), update the given
- reference table accordingly. */
+ zero, it specifies which port to use to talk to the host for
+ PROTOCOL. If NAME specifies a pool (as indicated by IS_POOL),
+ update the given reference table accordingly. */
static void
add_host (const char *name, int is_pool,
- const dns_addrinfo_t ai, unsigned short port,
- int *reftbl, size_t reftblsize, int *refidx)
+ const dns_addrinfo_t ai,
+ enum ks_protocol protocol, unsigned short port)
{
gpg_error_t tmperr;
char *tmphost;
int idx, tmpidx;
+ hostinfo_t host;
int i;
idx = find_hostinfo (name);
+ host = hosttable[idx];
if (is_pool)
{
@@ -325,7 +346,7 @@ add_host (const char *name, int is_pool,
log_info ("resolve_dns_addr failed while checking '%s': %s\n",
name, gpg_strerror (tmperr));
}
- else if ((*refidx) + 1 >= reftblsize)
+ else if (host->pool_len + 1 >= MAX_POOL_SIZE)
{
log_error ("resolve_dns_addr for '%s': '%s'"
" [index table full - ignored]\n", name, tmphost);
@@ -352,7 +373,7 @@ add_host (const char *name, int is_pool,
else /* Set or update the entry. */
{
if (port)
- hosttable[tmpidx]->port = port;
+ hosttable[tmpidx]->port[protocol] = port;
if (ai->family == AF_INET6)
{
@@ -365,17 +386,54 @@ add_host (const char *name, int is_pool,
else
BUG ();
- for (i=0; i < *refidx; i++)
- if (reftbl[i] == tmpidx)
- break;
- if (!(i < *refidx) && tmpidx != idx)
- reftbl[(*refidx)++] = tmpidx;
+ /* If we updated the main entry, we're done. */
+ if (idx == tmpidx)
+ goto leave;
+
+ /* If we updated an existing entry, we're done. */
+ for (i = 0; i < host->pool_len; i++)
+ if (host->pool[i] == tmpidx)
+ goto leave;
+
+ /* Otherwise, we need to add it to the pool. Check if there
+ is space. */
+ if (host->pool_len + 1 > host->pool_size)
+ {
+ int *new_pool;
+ size_t new_size;
+
+ if (host->pool_size == 0)
+ new_size = 4;
+ else
+ new_size = host->pool_size * 2;
+
+ new_pool = xtryrealloc (host->pool,
+ new_size * sizeof *new_pool);
+
+ if (new_pool == NULL)
+ goto leave;
+
+ host->pool = new_pool;
+ host->pool_size = new_size;
+ }
+
+ /* Finally, add it. */
+ log_assert (host->pool_len < host->pool_size);
+ host->pool[host->pool_len++] = tmpidx;
}
}
+ leave:
xfree (tmphost);
}
+/* Sort the pool of the given hostinfo HI. */
+static void
+hostinfo_sort_pool (hostinfo_t hi)
+{
+ qsort (hi->pool, hi->pool_len, sizeof *hi->pool, sort_hostpool);
+}
+
/* 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
@@ -393,12 +451,16 @@ add_host (const char *name, int is_pool,
* pool. */
static gpg_error_t
map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
- char **r_host, char *r_portstr,
+ enum ks_protocol protocol, char **r_host, char *r_portstr,
unsigned int *r_httpflags, char **r_httphost)
{
gpg_error_t err = 0;
hostinfo_t hi;
int idx;
+ dns_addrinfo_t aibuf, ai;
+ int is_pool;
+ int new_hosts = 0;
+ char *cname;
*r_host = NULL;
if (r_httpflags)
@@ -415,74 +477,62 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
/* See whether the host is in our table. */
idx = find_hostinfo (name);
- if (idx == -1 && is_onion_address (name))
+ if (idx == -1)
{
idx = create_new_hostinfo (name);
if (idx == -1)
return gpg_error_from_syserror ();
hi = hosttable[idx];
- hi->onion = 1;
+ hi->onion = is_onion_address (name);
}
- else if (idx == -1)
+ else
+ hi = hosttable[idx];
+
+ is_pool = hi->pool != NULL;
+
+ if (srvtag && !is_ip_address (name)
+ && ! hi->onion
+ && ! (hi->did_srv_lookup & 1 << protocol))
{
- /* We never saw this host. Allocate a new entry. */
- dns_addrinfo_t aibuf, ai;
- int *reftbl;
- size_t reftblsize;
- int refidx;
- int is_pool = 0;
- char *cname;
struct srventry *srvs;
unsigned int srvscount;
- reftblsize = 100;
- reftbl = xtrymalloc (reftblsize * sizeof *reftbl);
- if (!reftbl)
- return gpg_error_from_syserror ();
- refidx = 0;
-
- idx = create_new_hostinfo (name);
- if (idx == -1)
+ /* Check for SRV records. */
+ err = get_dns_srv (name, srvtag, NULL, &srvs, &srvscount);
+ if (err)
{
- err = gpg_error_from_syserror ();
- xfree (reftbl);
+ if (gpg_err_code (err) == GPG_ERR_ECONNREFUSED)
+ tor_not_running_p (ctrl);
return err;
}
- hi = hosttable[idx];
- if (srvtag && !is_ip_address (name))
+ if (srvscount > 0)
{
- /* Check for SRV records. */
- err = get_dns_srv (name, srvtag, NULL, &srvs, &srvscount);
- if (err)
- {
- xfree (reftbl);
- if (gpg_err_code (err) == GPG_ERR_ECONNREFUSED)
- tor_not_running_p (ctrl);
- return err;
- }
+ int i;
+ if (! is_pool)
+ is_pool = srvscount > 1;
- if (srvscount > 0)
+ for (i = 0; i < srvscount; i++)
{
- int i;
- is_pool = srvscount > 1;
-
- for (i = 0; i < srvscount; i++)
- {
- err = resolve_dns_name (srvs[i].target, 0,
- AF_UNSPEC, SOCK_STREAM,
- &ai, &cname);
- if (err)
- continue;
- dirmngr_tick (ctrl);
- add_host (name, is_pool, ai, srvs[i].port,
- reftbl, reftblsize, &refidx);
- }
-
- xfree (srvs);
+ err = resolve_dns_name (srvs[i].target, 0,
+ AF_UNSPEC, SOCK_STREAM,
+ &ai, &cname);
+ if (err)
+ continue;
+ dirmngr_tick (ctrl);
+ add_host (name, is_pool, ai, protocol, srvs[i].port);
+ new_hosts = 1;
}
+
+ xfree (srvs);
}
+ hi->did_srv_lookup |= 1 << protocol;
+ }
+
+ if (! hi->did_a_lookup
+ && ! hi->onion)
+ {
/* Find all A records for this entry and put them into the pool
list - if any. */
err = resolve_dns_name (name, 0, 0, SOCK_STREAM, &aibuf, &cname);
@@ -516,32 +566,18 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
continue;
dirmngr_tick (ctrl);
- add_host (name, is_pool, ai, 0, reftbl, reftblsize, &refidx);
+ add_host (name, is_pool, ai, 0, 0);
+ new_hosts = 1;
}
+
+ hi->did_a_lookup = 1;
}
- reftbl[refidx] = -1;
xfree (cname);
free_dns_addrinfo (aibuf);
-
- if (refidx && is_pool)
- {
- assert (!hi->pool);
- hi->pool = xtryrealloc (reftbl, (refidx+1) * sizeof *reftbl);
- if (!hi->pool)
- {
- err = gpg_error_from_syserror ();
- log_error ("shrinking index table in map_host failed: %s\n",
- gpg_strerror (err));
- xfree (reftbl);
- return err;
- }
- qsort (hi->pool, refidx, sizeof *reftbl, sort_hostpool);
- }
- else
- xfree (reftbl);
}
+ if (new_hosts)
+ hostinfo_sort_pool (hi);
- hi = hosttable[idx];
if (hi->pool)
{
/* Deal with the pool name before selecting a host. */
@@ -563,7 +599,7 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
/* Select a host if needed. */
if (hi->poolidx == -1)
{
- hi->poolidx = select_random_host (hi->pool);
+ hi->poolidx = select_random_host (hi);
if (hi->poolidx == -1)
{
log_error ("no alive host found in pool '%s'\n", name);
@@ -586,7 +622,6 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
* find the canonical name so that it can be used in the HTTP
* Host header. Fixme: We should store that name in the
* hosttable. */
- dns_addrinfo_t aibuf, ai;
char *host;
err = resolve_dns_name (hi->name, 0, 0, SOCK_STREAM, &aibuf, NULL);
@@ -650,9 +685,9 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
}
return err;
}
- if (hi->port)
+ if (hi->port[protocol])
snprintf (r_portstr, 6 /* five digits and the sentinel */,
- "%hu", hi->port);
+ "%hu", hi->port[protocol]);
return 0;
}
@@ -740,7 +775,9 @@ ks_hkp_mark_host (ctrl_t ctrl, const char *name, int alive)
/* If the host is a pool mark all member hosts. */
if (!err && hi->pool)
{
- for (idx2=0; !err && (n=hi->pool[idx2]) != -1; idx2++)
+ for (idx2 = 0;
+ !err && idx2 < hi->pool_len && (n = hi->pool[idx2]) != -1;
+ idx2++)
{
assert (n >= 0 && n < hosttable_size);
@@ -753,7 +790,7 @@ ks_hkp_mark_host (ctrl_t ctrl, const char *name, int alive)
if (hosttable[idx3]
&& hosttable[idx3]->pool
&& idx3 != idx
- && host_in_pool_p (hosttable[idx3]->pool, n))
+ && host_in_pool_p (hosttable[idx3], n))
break;
}
if (idx3 < hosttable_size)
@@ -903,7 +940,7 @@ ks_hkp_print_hosttable (ctrl_t ctrl)
{
init_membuf (&mb, 256);
put_membuf_printf (&mb, " . -->");
- for (idx2=0; hi->pool[idx2] != -1; idx2++)
+ for (idx2 = 0; idx2 < hi->pool_len && hi->pool[idx2] != -1; idx2++)
{
put_membuf_printf (&mb, " %d", hi->pool[idx2]);
if (hi->poolidx == hi->pool[idx2])
@@ -971,6 +1008,7 @@ make_host_part (ctrl_t ctrl,
const char *srvtag;
char portstr[10];
char *hostname;
+ enum ks_protocol protocol;
*r_hostport = NULL;
@@ -978,15 +1016,17 @@ make_host_part (ctrl_t ctrl,
{
scheme = "https";
srvtag = no_srv? NULL : "pgpkey-https";
+ protocol = KS_PROTOCOL_HKPS;
}
else /* HKP or HTTP. */
{
scheme = "http";
srvtag = no_srv? NULL : "pgpkey-http";
+ protocol = KS_PROTOCOL_HKP;
}
portstr[0] = 0;
- err = map_host (ctrl, host, srvtag, force_reselect,
+ err = map_host (ctrl, host, srvtag, force_reselect, protocol,
&hostname, portstr, r_httpflags, r_httphost);
if (err)
return err;
@@ -1122,9 +1162,16 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
int redirects_left = MAX_REDIRECTS;
estream_t fp = NULL;
char *request_buffer = NULL;
+ parsed_uri_t uri = NULL;
+ int is_onion;
*r_fp = NULL;
+ err = http_parse_uri (&uri, request, 0);
+ if (err)
+ goto leave;
+ is_onion = uri->onion;
+
err = http_session_new (&session, httphost,
((ctrl->http_no_crl? HTTP_FLAG_NO_CRL : 0)
| HTTP_FLAG_TRUST_DEF),
@@ -1132,6 +1179,7 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
if (err)
goto leave;
http_session_set_log_cb (session, cert_log_cb);
+ http_session_set_timeout (session, ctrl->timeout);
once_more:
err = http_open (&http,
@@ -1209,6 +1257,23 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
request, s?s:"[none]", http_get_status_code (http));
if (s && *s && redirects_left-- )
{
+ if (is_onion)
+ {
+ /* Make sure that an onion address only redirects to
+ * another onion address. */
+ http_release_parsed_uri (uri);
+ uri = NULL;
+ err = http_parse_uri (&uri, s, 0);
+ if (err)
+ goto leave;
+
+ if (! uri->onion)
+ {
+ err = gpg_error (GPG_ERR_FORBIDDEN);
+ goto leave;
+ }
+ }
+
xfree (request_buffer);
request_buffer = xtrystrdup (s);
if (request_buffer)
@@ -1257,6 +1322,7 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
http_close (http, 0);
http_session_release (session);
xfree (request_buffer);
+ http_release_parsed_uri (uri);
return err;
}
diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c
index 02269da..7fb7731 100644
--- a/dirmngr/ks-engine-http.c
+++ b/dirmngr/ks-engine-http.c
@@ -72,6 +72,13 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
int redirects_left = MAX_REDIRECTS;
estream_t fp = NULL;
char *request_buffer = NULL;
+ parsed_uri_t uri = NULL;
+ int is_onion;
+
+ err = http_parse_uri (&uri, url, 0);
+ if (err)
+ goto leave;
+ is_onion = uri->onion;
once_more:
/* Note that we only use the system provided certificates with the
@@ -83,6 +90,7 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
if (err)
goto leave;
http_session_set_log_cb (session, cert_log_cb);
+ http_session_set_timeout (session, ctrl->timeout);
*r_fp = NULL;
err = http_open (&http,
@@ -144,6 +152,23 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
url, s?s:"[none]", http_get_status_code (http));
if (s && *s && redirects_left-- )
{
+ if (is_onion)
+ {
+ /* Make sure that an onion address only redirects to
+ * another onion address. */
+ http_release_parsed_uri (uri);
+ uri = NULL;
+ err = http_parse_uri (&uri, s, 0);
+ if (err)
+ goto leave;
+
+ if (! uri->onion)
+ {
+ err = gpg_error (GPG_ERR_FORBIDDEN);
+ goto leave;
+ }
+ }
+
xfree (request_buffer);
request_buffer = xtrystrdup (s);
if (request_buffer)
@@ -185,5 +210,6 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
http_close (http, 0);
http_session_release (session);
xfree (request_buffer);
+ http_release_parsed_uri (uri);
return err;
}
diff --git a/dirmngr/ldap.c b/dirmngr/ldap.c
index d661a68..adf8307 100644
--- a/dirmngr/ldap.c
+++ b/dirmngr/ldap.c
@@ -363,6 +363,7 @@ parse_one_pattern (const char *pattern)
break;
case '*':
pattern++;
+ /* fall through */
default: /* Take as substring match. */
{
const char format[] = "(|(sn=*%s*)(|(cn=*%s*)(mail=*%s*)))";
diff --git a/dirmngr/loadswdb.c b/dirmngr/loadswdb.c
index 7791f68..bc00466 100644
--- a/dirmngr/loadswdb.c
+++ b/dirmngr/loadswdb.c
@@ -1,5 +1,6 @@
/* loadswdb.c - Load the swdb file from versions.gnupg.org
* Copyright (C) 2016 g10 Code GmbH
+ * Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik
*
* This file is part of GnuPG.
*
diff --git a/dirmngr/server.c b/dirmngr/server.c
index 237cb52..7ed6cde 100644
--- a/dirmngr/server.c
+++ b/dirmngr/server.c
@@ -2,6 +2,7 @@
* Copyright (C) 2002 Klarälvdalens Datakonsult AB
* Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2011, 2015 g10 Code GmbH
* Copyright (C) 2014, 2015, 2016 Werner Koch
+ * Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik
*
* This file is part of GnuPG.
*
@@ -307,8 +308,8 @@ strcpy_escaped_plus (char *d, const unsigned char *s)
}
-/* This function returns true if a Tor server is running. The sattus
- is cached for the current connection. */
+/* This function returns true if a Tor server is running. The status
+ * is cached for the current connection. */
static int
is_tor_running (ctrl_t ctrl)
{
@@ -842,6 +843,8 @@ cmd_wkd_get (assuan_context_t ctx, char *line)
opt_submission_addr = has_option (line, "--submission-address");
opt_policy_flags = has_option (line, "--policy-flags");
+ if (has_option (line, "--quick"))
+ ctrl->timeout = opt.connect_quick_timeout;
line = skip_options (line);
mbox = mailbox_from_userid (line);
@@ -893,7 +896,6 @@ cmd_wkd_get (assuan_context_t ctx, char *line)
}
}
xfree (srvs);
- log_debug ("srv: got '%s%s'\n", domain, portstr);
}
gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, mbox, strlen (mbox));
@@ -929,6 +931,13 @@ cmd_wkd_get (assuan_context_t ctx, char *line)
encodedhash,
NULL);
no_log = 1;
+ if (uri)
+ {
+ err = dirmngr_status_printf (ctrl, "SOURCE", "https://%s%s",
+ domain, portstr);
+ if (err)
+ goto leave;
+ }
}
if (!uri)
{
@@ -2123,7 +2132,8 @@ cmd_ks_search (assuan_context_t ctx, char *line)
char *p;
estream_t outfp;
- /* No options for now. */
+ if (has_option (line, "--quick"))
+ ctrl->timeout = opt.connect_quick_timeout;
line = skip_options (line);
/* Break the line down into an strlist. Each pattern is
@@ -2187,7 +2197,8 @@ cmd_ks_get (assuan_context_t ctx, char *line)
char *p;
estream_t outfp;
- /* No options for now. */
+ if (has_option (line, "--quick"))
+ ctrl->timeout = opt.connect_quick_timeout;
line = skip_options (line);
/* Break the line into a strlist. Each pattern is by
@@ -2251,7 +2262,8 @@ cmd_ks_fetch (assuan_context_t ctx, char *line)
gpg_error_t err;
estream_t outfp;
- /* No options for now. */
+ if (has_option (line, "--quick"))
+ ctrl->timeout = opt.connect_quick_timeout;
line = skip_options (line);
err = ensure_keyserver (ctrl); /* FIXME: Why do we needs this here? */
@@ -2770,6 +2782,24 @@ dirmngr_status_help (ctrl_t ctrl, const char *text)
return err;
}
+
+/* This function is similar to print_assuan_status but takes a CTRL
+ * arg instead of an assuan context as first argument. */
+gpg_error_t
+dirmngr_status_printf (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;
+}
+
+
/* Send a tick progress indicator back. Fixme: This is only done for
the currently active channel. */
gpg_error_t
diff --git a/dirmngr/t-http.c b/dirmngr/t-http.c
index a3a74dd..440633d 100644
--- a/dirmngr/t-http.c
+++ b/dirmngr/t-http.c
@@ -40,6 +40,7 @@
#include "../common/util.h"
#include "../common/logging.h"
+#include "dns-stuff.h"
#include "http.h"
#include <ksba.h>
@@ -203,6 +204,7 @@ main (int argc, char **argv)
int no_crl = 0;
const char *cafile = NULL;
http_session_t session = NULL;
+ unsigned int timeout = 0;
gpgrt_init ();
log_set_prefix (PGM, GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_PID);
@@ -224,6 +226,7 @@ main (int argc, char **argv)
" --debug flyswatter\n"
" --tls-debug N use TLS debug level N\n"
" --cacert FNAME expect CA certificate in file FNAME\n"
+ " --timeout MS timeout for connect in MS\n"
" --no-verify do not verify the certificate\n"
" --force-tls use HTTP_FLAG_FORCE_TLS\n"
" --force-tor use HTTP_FLAG_FORCE_TOR\n"
@@ -261,6 +264,15 @@ main (int argc, char **argv)
argc--; argv++;
}
}
+ else if (!strcmp (*argv, "--timeout"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ timeout = strtoul (*argv, NULL, 10);
+ argc--; argv++;
+ }
+ }
else if (!strcmp (*argv, "--no-verify"))
{
no_verify = 1;
@@ -301,9 +313,25 @@ main (int argc, char **argv)
if (!cafile)
cafile = prepend_srcdir ("tls-ca.pem");
+ if (verbose)
+ my_http_flags |= HTTP_FLAG_LOG_RESP;
+
+ if (verbose || debug)
+ http_set_verbose (verbose, debug);
+
/* http.c makes use of the assuan socket wrapper. */
assuan_sock_init ();
+ if ((my_http_flags & HTTP_FLAG_FORCE_TOR))
+ {
+ enable_dns_tormode (1);
+ if (assuan_sock_set_flag (ASSUAN_INVALID_FD, "tor-mode", 1))
+ {
+ log_error ("error enabling Tor mode: %s\n", strerror (errno));
+ log_info ("(is your Libassuan recent enough?)\n");
+ }
+ }
+
#if HTTP_USE_NTBTLS
log_info ("new session.\n");
err = http_session_new (&session, NULL,
@@ -407,6 +435,9 @@ main (int argc, char **argv)
http_release_parsed_uri (uri);
uri = NULL;
+ if (session)
+ http_session_set_timeout (session, timeout);
+
rc = http_open_document (&hd, *argv, NULL, my_http_flags,
NULL, session, NULL, NULL);
if (rc)
diff --git a/doc/DETAILS b/doc/DETAILS
index 1624315..0be55f4 100644
--- a/doc/DETAILS
+++ b/doc/DETAILS
@@ -241,8 +241,7 @@ described here.
The origin of the key or the user ID. This is an integer
optionally followed by a space and an URL. This goes along with
- the previous field. The values are not yet defined.
-
+ the previous field. The URL is quoted in C style.
** Special fields
@@ -638,6 +637,23 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
This indicates that a signature subpacket was seen. The format is
the same as the "spk" record above.
+*** ENCRYPTION_COMPLIANCE_MODE <flags>
+ Indicates that the current encryption operation was in compliance
+ with the given set of modes for all recipients. "flags" is a
+ space separated list of numerical flags, see "Field 18 -
+ Compliance flags" above.
+
+*** DECRYPTION_COMPLIANCE_MODE <flags>
+ Indicates that the current decryption operation is in compliance
+ with the given set of modes. "flags" is a space separated list of
+ numerical flags, see "Field 18 - Compliance flags" above.
+
+*** VERIFICATION_COMPLIANCE_MODE <flags>
+ Indicates that the current signature verification operation is in
+ compliance with the given set of modes. "flags" is a space
+ separated list of numerical flags, see "Field 18 - Compliance
+ flags" above.
+
** Key related
*** INV_RECP, INV_SGNR
The two similar status codes:
@@ -1330,12 +1346,13 @@ CREATE TABLE signatures (
- 2 :: Key source on a user id (UID)
- 1 octet :: Key Source; i.e. the origin of the key:
- 0 :: Unknown source.
- - 1 :: Direct import from a file.
- - 2 :: Public keyserver.
- - 3 :: Preferred keysrver.
+ - 1 :: Public keyserver.
+ - 2 :: Preferred keyserver.
+ - 3 :: OpenPGP DANE.
- 4 :: Web Key Directory.
- - 5 :: Web Key Directory via sub-domain.
- - 6 :: OpenPGP DANE.
+ - 5 :: Import from a trusted URL.
+ - 6 :: Import from a trusted file.
+ - 7 :: Self generated.
- 4 octets :: Time of last update. This is a a four-octet scalar
with the seconds since Epoch.
- 1 octet :: Scalar with the length of the following field.
@@ -1520,5 +1537,5 @@ Description of some debug flags:
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"
+ directly followed by a combination of "a" (for authentication), "s"
(for signing), or "c" (for certification).
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 0c78284..89079b3 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -68,7 +68,7 @@ nobase_dist_doc_DATA = FAQ DETAILS HACKING DCO TRANSLATE OpenPGP KEYSERVER \
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 dirmngr.texi \
+ sysnotes.texi dirmngr.texi wks.texi \
gnupg-module-overview.svg \
gnupg-card-architecture.fig \
howtos.texi howto-create-a-server-cert.texi
@@ -88,11 +88,11 @@ YAT2M_OPTIONS = -I $(srcdir) \
--release "GnuPG @PACKAGE_VERSION@" --source "GNU Privacy Guard 2.1"
myman_sources = gnupg7.texi gpg.texi gpgsm.texi gpg-agent.texi \
- dirmngr.texi scdaemon.texi tools.texi
+ dirmngr.texi scdaemon.texi tools.texi wks.texi
myman_pages = gpgsm.1 gpg-agent.1 dirmngr.8 scdaemon.1 \
watchgnupg.1 gpgconf.1 addgnupghome.8 gpg-preset-passphrase.1 \
gpg-connect-agent.1 gpgparsemail.1 symcryptrun.1 \
- applygnupgdefaults.8 \
+ applygnupgdefaults.8 gpg-wks-client.1 gpg-wks-server.1 \
dirmngr-client.1
if USE_GPG2_HACK
myman_pages += gpg2.1 gpgv2.1
@@ -146,12 +146,12 @@ yat2m-stamp: $(myman_sources) defs.inc
@touch yat2m-stamp.tmp
incd="`test -f defsincdate || echo '$(srcdir)/'`defsincdate"; \
for file in $(myman_sources) ; do \
- ./yat2m $(YAT2M_OPTIONS) --store \
+ $(YAT2M) $(YAT2M_OPTIONS) --store \
--date "`cat $$incd 2>/dev/null`" \
`test -f '$$file' || echo '$(srcdir)/'`$$file ; done
@mv -f yat2m-stamp.tmp $@
-yat2m-stamp: yat2m
+yat2m-stamp: $(YAT2M)
$(myman_pages) gnupg.7 : yat2m-stamp defs.inc
@if test -f $@; then :; else \
diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi
index 22a7943..eef78a8 100644
--- a/doc/dirmngr.texi
+++ b/doc/dirmngr.texi
@@ -243,10 +243,16 @@ Enabling this option forces loading of expired CRLs; this is only
useful for debugging.
@item --use-tor
+@itemx --no-use-tor
@opindex use-tor
-This option switches Dirmngr and thus GnuPG into ``Tor mode'' to route
-all network access via Tor (an anonymity network). Certain other
-features are disabled if this mode is active.
+@opindex no-use-tor
+The option @option{--use-tor} switches Dirmngr and thus GnuPG into
+``Tor mode'' to route all network access via Tor (an anonymity
+network). Certain other features are disabled in this mode. The
+effect of @option{--use-tor} cannot be overridden by any other command
+or even be reloading gpg-agent. The use of @option{--no-use-tor}
+disables the use of Tor. The default is to use Tor if it is available
+on startup or after reloading dirmngr.
@item --standard-resolver
@opindex standard-resolver
@@ -260,9 +266,22 @@ Implemented'' if this function is used.
When possible use a recursive resolver instead of a stub resolver.
@item --resolver-timeout @var{n}
+@opindex resolver-timeout
Set the timeout for the DNS resolver to N seconds. The default are 30
seconds.
+@item --connect-timeout @var{n}
+@item --connect-quick-timeout @var{n}
+@opindex connect-timeout
+@opindex connect-quick-timeout
+Set the timeout for HTTP and generic TCP connection attempts to N
+seconds. The value set with the quick variant is used when the
+--quick option has been given to certain Assuan commands. The quick
+value is capped at the value of the regular connect timeout. The
+default values are 15 and 2 seconds. Note that the timeout values are
+for each connection attempt; the connection code will attempt to
+connect all addresses listed for a server.
+
@item --allow-version-check
@opindex allow-version-check
Allow Dirmngr to connect to @code{https://versions.gnupg.org} to get
diff --git a/doc/examples/vsnfd.prf b/doc/examples/vsnfd.prf
index 17c6d4c..e8732de 100644
--- a/doc/examples/vsnfd.prf
+++ b/doc/examples/vsnfd.prf
@@ -2,7 +2,7 @@
[gpg]
compliance de-vs
-default-new-key-algo brainpoolP256r1+brainpoolP256r1
+default-new-key-algo rsa3072/cert,sign+rsa3072/encr
[gpgsm]
enable-crl-checks
diff --git a/doc/faq.org b/doc/faq.org
index f038508..ddbeafa 100644
--- a/doc/faq.org
+++ b/doc/faq.org
@@ -6,9 +6,8 @@
#+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" />
+#+LINK: gnupgweb https://www.gnupg.org/
+#+STYLE: <link rel="stylesheet" type="text/css" href="https://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.
@@ -29,9 +28,9 @@ update this FAQ in the next month. See the section "Changes" for recent updates
: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.
+ [[https://www.gnupg.org/faq/GnuPG-FAQ.html]]; \\
+ a plain text version at \\
+ https://gnupg.org/ftp/gcrypt/gnupg/GnuPG-FAQ.txt .
See the end of this file for the release date.
@@ -89,7 +88,7 @@ update this FAQ in the next month. See the section "Changes" for recent updates
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
+ Internet standard as described in [[https://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?
@@ -158,8 +157,8 @@ update this FAQ in the next month. See the section "Changes" for recent updates
: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]].
+ You can download the GNU Privacy Guard from its primary server
+ [[https://gnupg.org/ftp/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
@@ -1139,8 +1138,8 @@ update this FAQ in the next month. See the section "Changes" for recent updates
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]].
+ gnupg-devel list. Otherwise, use the bug tracking system at
+ [[https://bugs.gnupg.org][bugs.gnupg.org]].
** Why doesn't GnuPG support X.509 certificates?
:PROPERTIES:
@@ -1177,7 +1176,7 @@ update this FAQ in the next month. See the section "Changes" for recent updates
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]].
+ [[https://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:
@@ -1203,7 +1202,7 @@ update this FAQ in the next month. See the section "Changes" for recent updates
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]].
+ [[https://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:
@@ -1480,7 +1479,7 @@ 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
+https://www.gnu.org/prep/maintain/html_node/Copyright-Papers.html for
details.
** U.S. export restrictions
@@ -1504,8 +1503,8 @@ 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
+The rules: https://www.bis.doc.gov/encryption/pubavailencsourcecodenofify.html
+The 2004 rule change: https://edocket.access.gpo.gov/2004/04-26992.htm
* Acknowledgements
diff --git a/doc/gnupg.texi b/doc/gnupg.texi
index c99c129..7154fc8 100644
--- a/doc/gnupg.texi
+++ b/doc/gnupg.texi
@@ -45,7 +45,7 @@ Published by The GnuPG Project@*
@copyright{} 2002, 2004, 2005, 2006, 2007, 2010 Free Software Foundation, Inc.@*
@copyright{} 2013, 2014, 2015 Werner Koch.@*
-@copyright{} 2015 g10 Code GmbH.
+@copyright{} 2015, 2016, 2017 g10 Code GmbH.
@quotation
Permission is granted to copy, distribute and/or modify this document
@@ -142,6 +142,7 @@ the administration and the architecture.
* Specify a User ID:: How to Specify a User Id.
* Helper Tools:: Description of small helper tools
+* Web Key Service:: Tools for the Web Key Service
* Howtos:: How to do certain things.
* System Notes:: Notes pertaining to certain OSes.
@@ -180,6 +181,7 @@ the administration and the architecture.
@include tools.texi
+@include wks.texi
@include howtos.texi
diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi
index 6ed0ff8..d61dc85 100644
--- a/doc/gpg-agent.texi
+++ b/doc/gpg-agent.texi
@@ -636,6 +636,13 @@ and allows the use of gpg-agent with the ssh implementation
@command{putty}. This is similar to the regular ssh-agent support but
makes use of Windows message queue as required by @command{putty}.
+@anchor{option --ssh-fingerprint-digest}
+@item --ssh-fingerprint-digest
+@opindex ssh-fingerprint-digest
+
+Select the digest algorithm used to compute ssh fingerprints that are
+communicated to the user, e.g. in pinentry dialogs. OpenSSH has
+transitioned from using MD5 to the more secure SHA256.
@end table
diff --git a/doc/gpg.texi b/doc/gpg.texi
index 1a0ea55..1984445 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -301,7 +301,7 @@ and other programs.
@itemx -K
@opindex list-secret-keys
List the specified secret keys. If no keys are specified, then all
-known secret keys are listed. A @code{#} after the intial tags
+known secret keys are listed. A @code{#} after the initial tags
@code{sec} or @code{ssb} means that the secret key or subkey is
currently not usable. We also say that this key has been taken
offline (for example, a primary key can be taken offline by exported
@@ -392,13 +392,13 @@ Present a menu to allow changing the PIN of a smartcard. This
functionality is also available as the subcommand "passwd" with the
@option{--edit-card} command.
-@item --delete-keys @code{name}
+@item --delete-keys @var{name}
@opindex delete-keys
Remove key from the public keyring. In batch mode either @option{--yes} is
required or the key must be specified by fingerprint. This is a
safeguard against accidental deletion of multiple keys.
-@item --delete-secret-keys @code{name}
+@item --delete-secret-keys @var{name}
@opindex delete-secret-keys
Remove key from the secret keyring. In batch mode the key must be
specified by fingerprint. The option @option{--yes} can be used to
@@ -408,7 +408,7 @@ secret key (as controlled by gpg-agent) is only used for the given
OpenPGP public key.
-@item --delete-secret-and-public-key @code{name}
+@item --delete-secret-and-public-key @var{name}
@opindex delete-secret-and-public-key
Same as @option{--delete-key}, but if a secret key exists, it will be
removed first. In batch mode the key must be specified by fingerprint.
@@ -423,13 +423,14 @@ those of the given name. The exported keys are written to STDOUT or to the
file given with option @option{--output}. Use together with
@option{--armor} to mail those keys.
-@item --send-keys @code{key IDs}
+@item --send-keys @var{keyIDs}
@opindex send-keys
Similar to @option{--export} but sends the keys to a keyserver.
-Fingerprints may be used instead of key IDs. Option @option{--keyserver}
-must be used to give the name of this keyserver. Don't send your
-complete keyring to a keyserver --- select only those keys which are new
-or changed by you. If no key IDs are given, @command{@gpgname} does nothing.
+Fingerprints may be used instead of key IDs. Option
+@option{--keyserver} must be used to give the name of this
+keyserver. Don't send your complete keyring to a keyserver --- select
+only those keys which are new or changed by you. If no @var{keyIDs}
+are given, @command{@gpgname} does nothing.
@item --export-secret-keys
@itemx --export-secret-subkeys
@@ -478,11 +479,11 @@ Most notable here is the @option{--import-options merge-only} option
which does not insert new keys but does only the merging of new
signatures, user-IDs and subkeys.
-@item --receive-keys @code{key IDs}
+@item --receive-keys @var{keyIDs}
@opindex receive-keys
-@itemx --recv-keys @code{key IDs}
+@itemx --recv-keys @var{keyIDs}
@opindex recv-keys
-Import the keys with the given key IDs from a keyserver. Option
+Import the keys with the given @var{keyIDs} from a keyserver. Option
@option{--keyserver} must be used to give the name of this keyserver.
@item --refresh-keys
@@ -494,9 +495,9 @@ the entire keyring. Option @option{--keyserver} must be used to give the
name of the keyserver for all keys that do not have preferred keyservers
set (see @option{--keyserver-options honor-keyserver-url}).
-@item --search-keys @code{names}
+@item --search-keys @var{names}
@opindex search-keys
-Search the keyserver for the given names. Multiple names given here will
+Search the keyserver for the given @var{names}. Multiple names given here will
be joined together to create the search string for the keyserver.
Option @option{--keyserver} must be used to give the name of this
keyserver. Keyservers that support different search methods allow using
@@ -504,9 +505,9 @@ the syntax specified in "How to specify a user ID" below. Note that
different keyserver types support different search methods. Currently
only LDAP supports them all.
-@item --fetch-keys @code{URIs}
+@item --fetch-keys @var{URIs}
@opindex fetch-keys
-Retrieve keys located at the specified URIs. Note that different
+Retrieve keys located at the specified @var{URIs}. Note that different
installations of GnuPG may support different protocols (HTTP, FTP,
LDAP, etc.). When using HTTPS the system provided root certificates
are used by this command.
@@ -572,14 +573,14 @@ When updating from version 1.0.6 to 1.0.7 this command should be used
to create signature caches in the keyring. It might be handy in other
situations too.
-@item --print-md @code{algo}
+@item --print-md @var{algo}
@itemx --print-mds
@opindex print-md
-Print message digest of algorithm ALGO for all given files or STDIN.
-With the second form (or a deprecated "*" as algo) digests for all
+Print message digest of algorithm @var{algo} for all given files or STDIN.
+With the second form (or a deprecated "*" for @var{algo}) digests for all
available algorithms are printed.
-@item --gen-random @code{0|1|2} @code{count}
+@item --gen-random @var{0|1|2} @var{count}
@opindex gen-random
Emit @var{count} random bytes of the given quality level 0, 1 or 2. If
@var{count} is not given or zero, an endless sequence of random bytes
@@ -587,9 +588,10 @@ will be emitted. If used with @option{--armor} the output will be
base64 encoded. PLEASE, don't use this command unless you know what
you are doing; it may remove precious entropy from the system!
-@item --gen-prime @code{mode} @code{bits}
+@item --gen-prime @var{mode} @var{bits}
@opindex gen-prime
-Use the source, Luke :-). The output format is still subject to change.
+Use the source, Luke :-). The output format is subject to change
+with ant release.
@item --enarmor
@@ -599,11 +601,11 @@ Use the source, Luke :-). The output format is still subject to change.
Pack or unpack an arbitrary input into/from an OpenPGP ASCII armor.
This is a GnuPG extension to OpenPGP and in general not very useful.
-@item --tofu-policy @code{auto|good|unknown|bad|ask} @code{key...}
+@item --tofu-policy @{auto|good|unknown|bad|ask@} @var{keys}
@opindex tofu-policy
Set the TOFU policy for all the bindings associated with the specified
-keys. For more information about the meaning of the policies,
-@pxref{trust-model-tofu}. The keys may be specified either by their
+@var{keys}. For more information about the meaning of the policies,
+@pxref{trust-model-tofu}. The @var{keys} may be specified either by their
fingerprint (preferred) or their keyid.
@c @item --server
@@ -624,7 +626,7 @@ This section explains the main commands for key management.
@table @gnupgtabopt
-@item --quick-generate-key @code{user-id} [@code{algo} [@code{usage} [@code{expire}]]]
+@item --quick-generate-key @var{user-id} [@var{algo} [@var{usage} [@var{expire}]]]
@opindex quick-generate-key
This is a simple command to generate a standard key with one user id.
In contrast to @option{--generate-key} the key is generated directly
@@ -637,16 +639,16 @@ answer to a ``Continue?'' style confirmation prompt is required. In
case the user id already exists in the keyring a second prompt to
force the creation of the key will show up.
-If @code{algo} or @code{usage} are given, only the primary key is
+If @var{algo} or @var{usage} are given, only the primary key is
created and no prompts are shown. To specify an expiration date but
still create a primary and subkey use ``default'' or
-``future-default'' for @code{algo} and ``default'' for @code{usage}.
+``future-default'' for @var{algo} and ``default'' for @var{usage}.
For a description of these optional arguments see the command
-@code{--quick-add-key}. The @code{usage} accepts also the value
+@code{--quick-add-key}. The @var{usage} accepts also the value
``cert'' which can be used to create a certification only primary key;
the default is to a create certification and signing key.
-The @code{expire} argument can be used to specify an expiration date
+The @var{expire} argument can be used to specify an expiration date
for the key. Several formats are supported; commonly the ISO formats
``YYYY-MM-DD'' or ``YYYYMMDDThhmmss'' are used. To make the key
expire in N seconds, N days, N weeks, N months, or N years use
@@ -663,20 +665,26 @@ supplied passphrase is used for the new key and the agent does not ask
for it. To create a key without any protection @code{--passphrase ''}
may be used.
-@item --quick-set-expire @code{fpr} @code{expire}
+@item --quick-set-expire @var{fpr} @var{expire} [*|@var{subfprs}]
@opindex quick-set-expire
-Directly set the expiration time of the primary key to @code{expire}.
-To remove the expiration time @code{0} can be used.
+With two arguments given, directly set the expiration time of the
+primary key identified by @var{fpr} to @var{expire}. To remove the
+expiration time @code{0} can be used. With three arguments and the
+third given as an asterisk, the expiration time of all non-revoked and
+not yet expired subkeys are set to @var{expire}. With more than two
+arguments and a list of fingerprints given for @var{subfprs}, all
+non-revoked subkeys matching these fingerprints are set to
+@var{expire}.
-@item --quick-add-key @code{fpr} [@code{algo} [@code{usage} [@code{expire}]]]
+@item --quick-add-key @var{fpr} [@var{algo} [@var{usage} [@var{expire}]]]
@opindex quick-add-key
Directly add a subkey to the key identified by the fingerprint
-@code{fpr}. Without the optional arguments an encryption subkey is
+@var{fpr}. Without the optional arguments an encryption subkey is
added. If any of the arguments are given a more specific subkey is
added.
-@code{algo} may be any of the supported algorithms or curve names
+@var{algo} may be any of the supported algorithms or curve names
given in the format as used by key listings. To use the default
algorithm the string ``default'' or ``-'' can be used. Supported
algorithms are ``rsa'', ``dsa'', ``elg'', ``ed25519'', ``cv25519'',
@@ -686,9 +694,9 @@ key length is 4096 bits. The string ``future-default'' is an alias
for the algorithm which will likely be used as default algorithm in
future versions of gpg.
-Depending on the given @code{algo} the subkey may either be an
+Depending on the given @var{algo} the subkey may either be an
encryption subkey or a signing subkey. If an algorithm is capable of
-signing and encryption and such a subkey is desired, a @code{usage}
+signing and encryption and such a subkey is desired, a @var{usage}
string must be given. This string is either ``default'' or ``-'' to
keep the default or a comma delimited list (or space delimited list)
of keywords: ``sign'' for a signing subkey, ``auth'' for an
@@ -696,7 +704,7 @@ authentication subkey, and ``encr'' for an encryption subkey
(``encrypt'' can be used as alias for ``encr''). The valid
combinations depend on the algorithm.
-The @code{expire} argument can be used to specify an expiration date
+The @var{expire} argument can be used to specify an expiration date
for the key. Several formats are supported; commonly the ISO formats
``YYYY-MM-DD'' or ``YYYYMMDDThhmmss'' are used. To make the key
expire in N seconds, N days, N weeks, N months, or N years use
@@ -726,9 +734,9 @@ mode. See the manual section ``Unattended key generation'' on how
to use this.
-@item --generate-revocation @code{name}
+@item --generate-revocation @var{name}
@opindex generate-revocation
-@itemx --gen-revoke @code{name}
+@itemx --gen-revoke @var{name}
@opindex gen-revoke
Generate a revocation certificate for the complete key. To only revoke
a subkey or a key signature, use the @option{--edit} command.
@@ -743,9 +751,9 @@ published, which is best done by sending the key to a keyserver
to a file which is then send to frequent communication partners.
-@item --generate-designated-revocation @code{name}
+@item --generate-designated-revocation @var{name}
@opindex generate-designated-revocation
-@itemx --desig-revoke @code{name}
+@itemx --desig-revoke @var{name}
@opindex desig-revoke
Generate a designated revocation certificate for a key. This allows a
user (with the permission of the keyholder) to revoke someone else's
@@ -761,14 +769,14 @@ line.
@c ******** Begin Edit-key Options **********
@table @asis
- @item uid @code{n}
+ @item uid @var{n}
@opindex keyedit:uid
- Toggle selection of user ID or photographic user ID with index @code{n}.
+ Toggle selection of user ID or photographic user ID with index @var{n}.
Use @code{*} to select all and @code{0} to deselect all.
- @item key @code{n}
+ @item key @var{n}
@opindex keyedit:key
- Toggle selection of subkey with index @code{n} or key ID @code{n}.
+ Toggle selection of subkey with index @var{n} or key ID @var{n}.
Use @code{*} to select all and @code{0} to deselect all.
@item sign
@@ -893,9 +901,9 @@ signing.
not already included in the preference list. In addition, the
preferred keyserver and signature notations (if any) are shown.
- @item setpref @code{string}
+ @item setpref @var{string}
@opindex keyedit:setpref
- Set the list of user ID preferences to @code{string} for all (or just
+ Set the list of user ID preferences to @var{string} for all (or just
the selected) user IDs. Calling setpref with no arguments sets the
preference list to the default (either built-in or set via
@option{--default-preference-list}), and calling setpref with "none"
@@ -935,9 +943,9 @@ signing.
from the card - if the card gets broken your secret key will be lost
unless you have a backup somewhere.
- @item bkuptocard @code{file}
+ @item bkuptocard @var{file}
@opindex keyedit:bkuptocard
- Restore the given file to a card. This command may be used to restore a
+ Restore the given @var{file} to a card. This command may be used to restore a
backup key (as generated during card initialization) to a new card. In
almost all cases this will be the encryption key. You should use this
command only with the corresponding public key and make sure that the
@@ -1057,25 +1065,25 @@ the values:
@end table
@c ******** End Edit-key Options **********
-@item --sign-key @code{name}
+@item --sign-key @var{name}
@opindex sign-key
Signs a public key with your secret key. This is a shortcut version of
the subcommand "sign" from @option{--edit}.
-@item --lsign-key @code{name}
+@item --lsign-key @var{name}
@opindex lsign-key
Signs a public key with your secret key but marks it as
non-exportable. This is a shortcut version of the subcommand "lsign"
from @option{--edit-key}.
-@item --quick-sign-key @code{fpr} [@code{names}]
-@itemx --quick-lsign-key @code{fpr} [@code{names}]
+@item --quick-sign-key @var{fpr} [@var{names}]
+@itemx --quick-lsign-key @var{fpr} [@var{names}]
@opindex quick-sign-key
@opindex quick-lsign-key
Directly sign a key from the passphrase without any further user
-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
+interaction. The @var{fpr} must be the verified primary fingerprint
+of a key in the local keyring. If no @var{names} are given, all
+useful user ids are signed; with given [@var{names}] only useful user
ids matching one of theses names are signed. By default, or if a name
is prefixed with a '*', a case insensitive substring match is used.
If a name is prefixed with a '=' a case sensitive exact match is done.
@@ -1224,7 +1232,7 @@ do not want to feed data via STDIN, you should connect STDIN to
g@file{/dev/null}.
It is highly recommended to use this option along with the options
-@option{--status-fd} and @option{--with-colons} for any unattended of
+@option{--status-fd} and @option{--with-colons} for any unattended use of
@command{gpg}.
@item --no-tty
@@ -1242,7 +1250,7 @@ Assume "yes" on most questions.
Assume "no" on most questions.
-@item --list-options @code{parameters}
+@item --list-options @var{parameters}
@opindex list-options
This is a space or comma delimited string that gives options used when
listing keys and signatures (that is, @option{--list-keys},
@@ -1321,7 +1329,7 @@ give the opposite meaning. The options are:
@end table
-@item --verify-options @code{parameters}
+@item --verify-options @var{parameters}
@opindex verify-options
This is a space or comma delimited string that gives options used when
verifying signatures. Options can be prepended with a `no-' to give
@@ -1402,7 +1410,7 @@ Enable hash truncation for all DSA keys even for old DSA Keys up to
that older versions of GnuPG also required this flag to allow the
generation of DSA larger than 1024 bit.
-@item --photo-viewer @code{string}
+@item --photo-viewer @var{string}
@opindex photo-viewer
This is the command line that should be run to view a photo ID. "%i"
will be expanded to a filename containing the photo. "%I" does the
@@ -1420,7 +1428,7 @@ The default viewer is "xloadimage -fork -quiet -title 'KeyID 0x%k'
STDIN". Note that if your image viewer program is not secure, then
executing it from GnuPG does not make it secure.
-@item --exec-path @code{string}
+@item --exec-path @var{string}
@opindex exec-path
@efindex PATH
Sets a list of directories to search for photo viewers and keyserver
@@ -1430,9 +1438,9 @@ variable.
Note, that on W32 system this value is ignored when searching for
keyserver helpers.
-@item --keyring @code{file}
+@item --keyring @var{file}
@opindex keyring
-Add @code{file} to the current list of keyrings. If @code{file} begins
+Add @var{file} to the current list of keyrings. If @var{file} begins
with a tilde and a slash, these are replaced by the $HOME directory. If
the filename does not contain a slash, it is assumed to be in the GnuPG
home directory ("~/.gnupg" if @option{--homedir} or $GNUPGHOME is not
@@ -1446,20 +1454,20 @@ If the option @option{--no-keyring} has been used no keyrings will
be used at all.
-@item --secret-keyring @code{file}
+@item --secret-keyring @var{file}
@opindex secret-keyring
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.
-@item --primary-keyring @code{file}
+@item --primary-keyring @var{file}
@opindex primary-keyring
-Designate @code{file} as the primary public keyring. This means that
+Designate @var{file} as the primary public keyring. This means that
newly imported keys (via @option{--import} or keyserver
@option{--recv-from}) will go to this keyring.
-@item --trustdb-name @code{file}
+@item --trustdb-name @var{file}
@opindex trustdb-name
-Use @code{file} instead of the default trustdb. If @code{file} begins
+Use @var{file} instead of the default trustdb. If @var{file} begins
with a tilde and a slash, these are replaced by the $HOME directory. If
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
@@ -1468,7 +1476,7 @@ not used).
@include opt-homedir.texi
-@item --display-charset @code{name}
+@item --display-charset @var{name}
@opindex display-charset
Set the name of the native character set. This is used to convert
some informational strings like user IDs to the proper UTF-8 encoding.
@@ -1476,7 +1484,7 @@ Note that this has nothing to do with the character set of data to be
encrypted or signed; GnuPG does not recode user-supplied data. If
this option is not used, the default character set is determined from
the current locale. A verbosity level of 3 shows the chosen set.
-Valid values for @code{name} are:
+Valid values for @var{name} are:
@table @asis
@@ -1513,9 +1521,9 @@ encoded in the character set as specified by
arguments. Both options may be used multiple times.
@anchor{gpg-option --options}
-@item --options @code{file}
+@item --options @var{file}
@opindex options
-Read options from @code{file} and do not try to read them from the
+Read options from @var{file} and do not try to read them from the
default options file in the homedir (see @option{--homedir}). This
option is ignored if used in an options file.
@@ -1525,18 +1533,18 @@ Shortcut for @option{--options /dev/null}. This option is detected
before an attempt to open an option file. Using this option will also
prevent the creation of a @file{~/.gnupg} homedir.
-@item -z @code{n}
-@itemx --compress-level @code{n}
-@itemx --bzip2-compress-level @code{n}
+@item -z @var{n}
+@itemx --compress-level @var{n}
+@itemx --bzip2-compress-level @var{n}
@opindex compress-level
@opindex bzip2-compress-level
-Set compression level to @code{n} for the ZIP and ZLIB compression
+Set compression level to @var{n} for the ZIP and ZLIB compression
algorithms. The default is to use the default compression level of zlib
(normally 6). @option{--bzip2-compress-level} sets the compression level
for the BZIP2 compression algorithm (defaulting to 6 as well). This is a
different option from @option{--compress-level} since BZIP2 uses a
significant amount of memory for each additional compression level.
-@option{-z} sets both. A value of 0 for @code{n} disables compression.
+@option{-z} sets both. A value of 0 for @var{n} disables compression.
@item --bzip2-decompress-lowmem
@opindex bzip2-decompress-lowmem
@@ -1567,7 +1575,7 @@ information on the specific levels and how they are
used. @option{--no-ask-cert-level} disables this option. This option
defaults to no.
-@item --default-cert-level @code{n}
+@item --default-cert-level @var{n}
@opindex default-cert-level
The default to use for the check level when signing a key.
@@ -1604,7 +1612,7 @@ certification level below this as invalid. Defaults to 2, which
disregards level 1 signatures. Note that level 0 "no particular
claim" signatures are always accepted.
-@item --trusted-key @code{long key ID}
+@item --trusted-key @var{long key ID}
@opindex trusted-key
Assume that the specified key (which must be given
as a full 8 byte key ID) is as trustworthy as one of
@@ -1613,7 +1621,7 @@ don't want to keep your secret keys (or one of them)
online but still want to be able to check the validity of a given
recipient's or signator's key.
-@item --trust-model @code{pgp|classic|tofu|tofu+pgp|direct|always|auto}
+@item --trust-model @{pgp|classic|tofu|tofu+pgp|direct|always|auto@}
@opindex trust-model
Set what trust model GnuPG should follow. The models are:
@@ -1633,10 +1641,14 @@ Set what trust model GnuPG should follow. The models are:
@opindex trust-model:tofu
@anchor{trust-model-tofu}
TOFU stands for Trust On First Use. In this trust model, the first
- time a key is seen, it is memorized. If later another key is seen
- with a user id with the same email address, a warning is displayed
- indicating that there is a conflict and that the key might be a
- forgery and an attempt at a man-in-the-middle attack.
+ time a key is seen, it is memorized. If later another key with a
+ user id with the same email address is seen, both keys are marked as
+ suspect. In that case, the next time either is used, a warning is
+ displayed describing the conflict, why it might have occured
+ (either the user generated a new key and failed to cross sign the
+ old and new keys, the key is forgery, or a man-in-the-middle attack
+ is being attempted), and the user is prompted to manually confirm
+ the validity of the key in question.
Because a potential attacker is able to control the email address
and thereby circumvent the conflict detection algorithm by using an
@@ -1691,7 +1703,7 @@ Set what trust model GnuPG should follow. The models are:
@item direct
@opindex trust-model:direct
Key validity is set directly by the user and not calculated via the
- Web of Trust. This model is soley based on the key and does
+ Web of Trust. This model is solely based on the key and does
not distinguish user IDs. Note that when changing to another trust
model the trust values assigned to a key are transformed into
ownertrust values, which also indicate how you trust the owner of
@@ -1714,7 +1726,7 @@ Set what trust model GnuPG should follow. The models are:
exists.
@end table
-@item --auto-key-locate @code{parameters}
+@item --auto-key-locate @var{parameters}
@itemx --no-auto-key-locate
@opindex auto-key-locate
GnuPG can automatically locate and retrieve keys as needed using this
@@ -1790,7 +1802,7 @@ you naturally will not have on your local keyring), the operator can
tell both your IP address and the time when you verified the
signature.
-@item --keyid-format @code{none|short|0xshort|long|0xlong}
+@item --keyid-format @{none|short|0xshort|long|0xlong@}
@opindex keyid-format
Select how to display key IDs. "none" does not show the key ID at all
but shows the fingerprint in a separate line. "short" is the
@@ -1799,15 +1811,15 @@ convenient) 16-character key ID. Add an "0x" to either to include an
"0x" at the beginning of the key ID, as in 0x99242560. Note that this
option is ignored if the option @option{--with-colons} is used.
-@item --keyserver @code{name}
+@item --keyserver @var{name}
@opindex keyserver
This option is deprecated - please use the @option{--keyserver} in
@file{dirmngr.conf} instead.
-Use @code{name} as your keyserver. This is the server that
+Use @var{name} as your keyserver. This is the server that
@option{--receive-keys}, @option{--send-keys}, and @option{--search-keys}
will communicate with to receive keys from, send keys to, and search for
-keys on. The format of the @code{name} is a URI:
+keys on. The format of the @var{name} is a URI:
`scheme:[//]keyservername[:port]' The scheme is the type of keyserver:
"hkp" for the HTTP (or compatible) keyservers, "ldap" for the LDAP
keyservers, or "mailto" for the Graff email keyserver. Note that your
@@ -1822,7 +1834,7 @@ need to send keys to more than one server. The keyserver
@code{hkp://keys.gnupg.net} uses round robin DNS to give a different
keyserver each time you use it.
-@item --keyserver-options @code{name=value}
+@item --keyserver-options @{@var{name}=@var{value}@}
@opindex keyserver-options
This is a space or comma delimited string that gives options for the
keyserver. Options can be prefixed with a `no-' to give the opposite
@@ -1878,7 +1890,7 @@ are available for all keyserver types, some common options are:
timeout applies separately to each key retrieval, and not to the
@option{--receive-keys} command as a whole. Defaults to 30 seconds.
- @item http-proxy=@code{value}
+ @item http-proxy=@var{value}
This option is deprecated.
Set the proxy to use for HTTP and HKP keyservers.
This overrides any proxy defined in @file{dirmngr.conf}.
@@ -1901,22 +1913,22 @@ are available for all keyserver types, some common options are:
@end table
-@item --completes-needed @code{n}
+@item --completes-needed @var{n}
@opindex compliant-needed
Number of completely trusted users to introduce a new
key signer (defaults to 1).
-@item --marginals-needed @code{n}
+@item --marginals-needed @var{n}
@opindex marginals-needed
Number of marginally trusted users to introduce a new
key signer (defaults to 3)
-@item --tofu-default-policy @code{auto|good|unknown|bad|ask}
+@item --tofu-default-policy @{auto|good|unknown|bad|ask@}
@opindex tofu-default-policy
The default TOFU policy (defaults to @code{auto}). For more
information about the meaning of this option, @pxref{trust-model-tofu}.
-@item --max-cert-depth @code{n}
+@item --max-cert-depth @var{n}
@opindex max-cert-depth
Maximum depth of a certification chain (default is 5).
@@ -1998,9 +2010,9 @@ connected pipe too early. Using this option along with
@option{--enable-progress-filter} may be used to cleanly cancel long
running gpg operations.
-@item --limit-card-insert-tries @code{n}
+@item --limit-card-insert-tries @var{n}
@opindex limit-card-insert-tries
-With @code{n} greater than 0 the number of prompts asking to insert a
+With @var{n} greater than 0 the number of prompts asking to insert a
smartcard gets limited to N-1. Thus with a value of 1 gpg won't at
all ask to insert a card if none has been inserted at startup. This
option is useful in the configuration file in case an application does
@@ -2110,7 +2122,7 @@ encrypts to a key stored in the given file. @var{file} must be the
name of a file containing exactly one key. @command{@gpgname} assumes that
the key in this file is fully valid.
-@item --encrypt-to @code{name}
+@item --encrypt-to @var{name}
@opindex encrypt-to
Same as @option{--recipient} but this one is intended for use in the
options file and may be used with your own user-id as an
@@ -2119,7 +2131,7 @@ recipients given either by use of @option{--recipient} or by the asked
user id. No trust checking is performed for these user ids and even
disabled keys can be used.
-@item --hidden-encrypt-to @code{name}
+@item --hidden-encrypt-to @var{name}
@opindex hidden-encrypt-to
Same as @option{--hidden-recipient} but this one is intended for use in the
options file and may be used with your own user-id as a hidden
@@ -2133,7 +2145,7 @@ keys can be used.
Disable the use of all @option{--encrypt-to} and
@option{--hidden-encrypt-to} keys.
-@item --group @code{name=value}
+@item --group @{@var{name}=@var{value}@}
@opindex group
Sets up a named group, which is similar to aliases in email programs.
Any time the group name is a recipient (@option{-r} or
@@ -2149,7 +2161,7 @@ from the command line, it may be necessary to quote the argument to
this option to prevent the shell from treating it as multiple
arguments.
-@item --ungroup @code{name}
+@item --ungroup @var{name}
@opindex ungroup
Remove a given entry from the @option{--group} list.
@@ -2231,7 +2243,7 @@ Assume the input data is not in ASCII armored format.
Write output to @var{file}. To write to stdout use @code{-} as the
filename.
-@item --max-output @code{n}
+@item --max-output @var{n}
@opindex max-output
This option sets a limit on the number of bytes that will be generated
when processing a file. Since OpenPGP supports various levels of
@@ -2250,7 +2262,16 @@ hint to optimize its buffer allocation strategy. It is also used by
the @option{--status-fd} line ``PROGRESS'' to provide a value for
``total'' if that is not available by other means.
-@item --import-options @code{parameters}
+@item --key-origin @var{string}[,@var{url}]
+@opindex key-origin
+gpg can track the origin of a key. Certain origins are implicitly
+known (e.g. keyserver, web key directory) and set. For a standard
+import the origin of the keys imported can be set with this option.
+To list the possible values use "help" for @var{string}. Some origins
+can store an optional @var{url} argument. That URL can appended to
+@var{string} after a comma.
+
+@item --import-options @var{parameters}
@opindex import-options
This is a space or comma delimited string that gives options for
importing keys. Options can be prepended with a `no-' to give the
@@ -2304,6 +2325,10 @@ opposite meaning. The options are:
on the keyring. This option is the same as running the @option{--edit-key}
command "clean" after import. Defaults to no.
+ @item repair-keys. After import, fix various problems with the
+ keys. For example, this reorders signatures, and strips duplicate
+ signatures. Defaults to yes.
+
@item import-minimal
Import the smallest key possible. This removes all signatures except
the most recent self-signature on each user ID. This option is the
@@ -2317,8 +2342,8 @@ opposite meaning. The options are:
contradicting options are overridden.
@end table
-@item --import-filter @code{@var{name}=@var{expr}}
-@itemx --export-filter @code{@var{name}=@var{expr}}
+@item --import-filter @{@var{name}=@var{expr}@}
+@itemx --export-filter @{@var{name}=@var{expr}@}
@opindex import-filter
@opindex export-filter
These options define an import/export filter which are applied to the
@@ -2404,7 +2429,7 @@ The available properties are:
@end table
-@item --export-options @code{parameters}
+@item --export-options @var{parameters}
@opindex export-options
This is a space or comma delimited string that gives options for
exporting keys. Options can be prepended with a `no-' to give the
@@ -2418,9 +2443,10 @@ opposite meaning. The options are:
Defaults to no.
@item export-attributes
- Include attribute user IDs (photo IDs) while exporting. This is
- useful to export keys if they are going to be used by an OpenPGP
- program that does not accept attribute user IDs. Defaults to yes.
+ Include attribute user IDs (photo IDs) while exporting. Not
+ including attribute user IDs is useful to export keys that are going
+ to be used by an OpenPGP program that does not accept attribute user
+ IDs. Defaults to yes.
@item export-sensitive-revkeys
Include designated revoker information that was marked as
@@ -2516,6 +2542,13 @@ Print the ICAO spelling of the fingerprint in addition to the hex digits.
Include the keygrip in the key listings. In @code{--with-colons} mode
this is implicitly enable for secret keys.
+@item --with-key-origin
+@opindex with-key-origin
+Include the locally held information on the origin and last update of
+a key in a key listing. In @code{--with-colons} mode this is always
+printed. This data is currently experimental and shall not be
+considered part of the stable API.
+
@item --with-wkd-hash
@opindex with-wkd-hash
Print a Web Key Directory identifier along with each user ID in key
@@ -2575,9 +2608,9 @@ specified with @option{local-user} using a mail address. This
information can be helpful for verifier to locate the key; see
option @option{--auto-key-retrieve}.
-@item --personal-cipher-preferences @code{string}
+@item --personal-cipher-preferences @var{string}
@opindex personal-cipher-preferences
-Set the list of personal cipher preferences to @code{string}. Use
+Set the list of personal cipher preferences to @var{string}. Use
@command{@gpgname --version} to get a list of available algorithms,
and use @code{none} to set no preference at all. This allows the user
to safely override the algorithm chosen by the recipient key
@@ -2585,9 +2618,9 @@ preferences, as GPG will only select an algorithm that is usable by
all recipients. The most highly ranked cipher in this list is also
used for the @option{--symmetric} encryption command.
-@item --personal-digest-preferences @code{string}
+@item --personal-digest-preferences @var{string}
@opindex personal-digest-preferences
-Set the list of personal digest preferences to @code{string}. Use
+Set the list of personal digest preferences to @var{string}. Use
@command{@gpgname --version} to get a list of available algorithms,
and use @code{none} to set no preference at all. This allows the user
to safely override the algorithm chosen by the recipient key
@@ -2596,9 +2629,9 @@ all recipients. The most highly ranked digest algorithm in this list
is also used when signing without encryption
(e.g. @option{--clear-sign} or @option{--sign}).
-@item --personal-compress-preferences @code{string}
+@item --personal-compress-preferences @var{string}
@opindex personal-compress-preferences
-Set the list of personal compression preferences to @code{string}.
+Set the list of personal compression preferences to @var{string}.
Use @command{@gpgname --version} to get a list of available
algorithms, and use @code{none} to set no preference at all. This
allows the user to safely override the algorithm chosen by the
@@ -2607,26 +2640,26 @@ is usable by all recipients. The most highly ranked compression
algorithm in this list is also used when there are no recipient keys
to consider (e.g. @option{--symmetric}).
-@item --s2k-cipher-algo @code{name}
+@item --s2k-cipher-algo @var{name}
@opindex s2k-cipher-algo
-Use @code{name} as the cipher algorithm for symmetric encryption with
+Use @var{name} as the cipher algorithm for symmetric encryption with
a passphrase if @option{--personal-cipher-preferences} and
@option{--cipher-algo} are not given. The default is @value{GPGSYMENCALGO}.
-@item --s2k-digest-algo @code{name}
+@item --s2k-digest-algo @var{name}
@opindex s2k-digest-algo
-Use @code{name} as the digest algorithm used to mangle the passphrases
+Use @var{name} as the digest algorithm used to mangle the passphrases
for symmetric encryption. The default is SHA-1.
-@item --s2k-mode @code{n}
+@item --s2k-mode @var{n}
@opindex s2k-mode
Selects how passphrases for symmetric encryption are mangled. If
-@code{n} is 0 a plain passphrase (which is in general not recommended)
+@var{n} is 0 a plain passphrase (which is in general not recommended)
will be used, a 1 adds a salt (which should not be used) to the
passphrase and a 3 (the default) iterates the whole process a number
of times (see @option{--s2k-count}).
-@item --s2k-count @code{n}
+@item --s2k-count @var{n}
@opindex s2k-count
Specify how many times the passphrases mangling for symmetric
encryption is repeated. This value may range between 1024 and
@@ -2807,42 +2840,42 @@ Enable certain PROGRESS status outputs. This option allows frontends
to display a progress indicator while gpg is processing larger files.
There is a slight performance overhead using it.
-@item --status-fd @code{n}
+@item --status-fd @var{n}
@opindex status-fd
-Write special status strings to the file descriptor @code{n}.
+Write special status strings to the file descriptor @var{n}.
See the file DETAILS in the documentation for a listing of them.
-@item --status-file @code{file}
+@item --status-file @var{file}
@opindex status-file
Same as @option{--status-fd}, except the status data is written to file
-@code{file}.
+@var{file}.
-@item --logger-fd @code{n}
+@item --logger-fd @var{n}
@opindex logger-fd
-Write log output to file descriptor @code{n} and not to STDERR.
+Write log output to file descriptor @var{n} and not to STDERR.
-@item --log-file @code{file}
-@itemx --logger-file @code{file}
+@item --log-file @var{file}
+@itemx --logger-file @var{file}
@opindex log-file
Same as @option{--logger-fd}, except the logger data is written to
-file @code{file}. Use @file{socket://} to log to socket.
+file @var{file}. Use @file{socket://} to log to s socket.
-@item --attribute-fd @code{n}
+@item --attribute-fd @var{n}
@opindex attribute-fd
-Write attribute subpackets to the file descriptor @code{n}. This is most
+Write attribute subpackets to the file descriptor @var{n}. This is most
useful for use with @option{--status-fd}, since the status messages are
needed to separate out the various subpackets from the stream delivered
to the file descriptor.
-@item --attribute-file @code{file}
+@item --attribute-file @var{file}
@opindex attribute-file
Same as @option{--attribute-fd}, except the attribute data is written to
-file @code{file}.
+file @var{file}.
-@item --comment @code{string}
+@item --comment @var{string}
@itemx --no-comments
@opindex comment
-Use @code{string} as a comment string in cleartext signatures and ASCII
+Use @var{string} as a comment string in cleartext signatures and ASCII
armored messages or keys (see @option{--armor}). The default behavior is
not to use a comment string. @option{--comment} may be repeated multiple
times to get multiple comment strings. @option{--no-comments} removes
@@ -2861,21 +2894,21 @@ the micro is added, and given four times an operating system identification
is also emitted. @option{--no-emit-version} (default) disables the version
line.
-@item --sig-notation @code{name=value}
-@itemx --cert-notation @code{name=value}
-@itemx -N, --set-notation @code{name=value}
+@item --sig-notation @{@var{name}=@var{value}@}
+@itemx --cert-notation @{@var{name}=@var{value}@}
+@itemx -N, --set-notation @{@var{name}=@var{value}@}
@opindex sig-notation
@opindex cert-notation
@opindex set-notation
Put the name value pair into the signature as notation data.
-@code{name} must consist only of printable characters or spaces, and
+@var{name} must consist only of printable characters or spaces, and
must contain a '@@' character in the form keyname@@domain.example.com
(substituting the appropriate keyname and domain name, of course). This
is to help prevent pollution of the IETF reserved notation
namespace. The @option{--expert} flag overrides the '@@'
-check. @code{value} may be any printable string; it will be encoded in
+check. @var{value} may be any printable string; it will be encoded in
UTF-8, so you should check that your @option{--display-charset} is set
-correctly. If you prefix @code{name} with an exclamation mark (!), the
+correctly. If you prefix @var{name} with an exclamation mark (!), the
notation data will be flagged as critical
(rfc4880:5.2.3.16). @option{--sig-notation} sets a notation for data
signatures. @option{--cert-notation} sets a notation for key signatures
@@ -2893,13 +2926,13 @@ smartcard, and "%%" results in a single "%". %k, %K, and %f are only
meaningful when making a key signature (certification), and %c is only
meaningful when using the OpenPGP smartcard.
-@item --sig-policy-url @code{string}
-@itemx --cert-policy-url @code{string}
-@itemx --set-policy-url @code{string}
+@item --sig-policy-url @var{string}
+@itemx --cert-policy-url @var{string}
+@itemx --set-policy-url @var{string}
@opindex sig-policy-url
@opindex cert-policy-url
@opindex set-policy-url
-Use @code{string} as a Policy URL for signatures (rfc4880:5.2.3.20). If
+Use @var{string} as a Policy URL for signatures (rfc4880:5.2.3.20). If
you prefix it with an exclamation mark (!), the policy URL packet will
be flagged as critical. @option{--sig-policy-url} sets a policy url for
data signatures. @option{--cert-policy-url} sets a policy url for key
@@ -2907,19 +2940,19 @@ signatures (certifications). @option{--set-policy-url} sets both.
The same %-expandos used for notation data are available here as well.
-@item --sig-keyserver-url @code{string}
+@item --sig-keyserver-url @var{string}
@opindex sig-keyserver-url
-Use @code{string} as a preferred keyserver URL for data signatures. If
+Use @var{string} as a preferred keyserver URL for data signatures. If
you prefix it with an exclamation mark (!), the keyserver URL packet
will be flagged as critical.
The same %-expandos used for notation data are available here as well.
-@item --set-filename @code{string}
+@item --set-filename @var{string}
@opindex set-filename
-Use @code{string} as the filename which is stored inside messages.
+Use @var{string} as the filename which is stored inside messages.
This overrides the default, which is to use the actual filename of the
-file being encrypted. Using the empty string for @code{string}
+file being encrypted. Using the empty string for @var{string}
effectively removes the filename from the output.
@item --for-your-eyes-only
@@ -2937,9 +2970,9 @@ to display the message. This option overrides @option{--set-filename}.
Try to create a file with a name as embedded in the data. This can be
a dangerous option as it enables overwriting files. Defaults to no.
-@item --cipher-algo @code{name}
+@item --cipher-algo @var{name}
@opindex cipher-algo
-Use @code{name} as cipher algorithm. Running the program with the
+Use @var{name} as cipher algorithm. Running the program with the
command @option{--version} yields a list of supported algorithms. If
this is not used the cipher algorithm is selected from the preferences
stored with the key. In general, you do not want to use this option as
@@ -2947,17 +2980,17 @@ it allows you to violate the OpenPGP standard.
@option{--personal-cipher-preferences} is the safe way to accomplish the
same thing.
-@item --digest-algo @code{name}
+@item --digest-algo @var{name}
@opindex digest-algo
-Use @code{name} as the message digest algorithm. Running the program
+Use @var{name} as the message digest algorithm. Running the program
with the command @option{--version} yields a list of supported algorithms. In
general, you do not want to use this option as it allows you to
violate the OpenPGP standard. @option{--personal-digest-preferences} is the
safe way to accomplish the same thing.
-@item --compress-algo @code{name}
+@item --compress-algo @var{name}
@opindex compress-algo
-Use compression algorithm @code{name}. "zlib" is RFC-1950 ZLIB
+Use compression algorithm @var{name}. "zlib" is RFC-1950 ZLIB
compression. "zip" is RFC-1951 ZIP compression which is used by PGP.
"bzip2" is a more modern compression scheme that can compress some
things better than zip or zlib, but at the cost of more memory used
@@ -2978,24 +3011,24 @@ general, you do not want to use this option as it allows you to
violate the OpenPGP standard. @option{--personal-compress-preferences} is the
safe way to accomplish the same thing.
-@item --cert-digest-algo @code{name}
+@item --cert-digest-algo @var{name}
@opindex cert-digest-algo
-Use @code{name} as the message digest algorithm used when signing a
+Use @var{name} as the message digest algorithm used when signing a
key. Running the program with the command @option{--version} yields a
list of supported algorithms. Be aware that if you choose an algorithm
that GnuPG supports but other OpenPGP implementations do not, then some
users will not be able to use the key signatures you make, or quite
possibly your entire key.
-@item --disable-cipher-algo @code{name}
+@item --disable-cipher-algo @var{name}
@opindex disable-cipher-algo
-Never allow the use of @code{name} as cipher algorithm.
+Never allow the use of @var{name} as cipher algorithm.
The given name will not be checked so that a later loaded algorithm
will still get disabled.
-@item --disable-pubkey-algo @code{name}
+@item --disable-pubkey-algo @var{name}
@opindex disable-pubkey-algo
-Never allow the use of @code{name} as public key algorithm.
+Never allow the use of @var{name} as public key algorithm.
The given name will not be checked so that a later loaded algorithm
will still get disabled.
@@ -3031,44 +3064,44 @@ signatures to prevent the mail system from breaking the signature. Note
that all other PGP versions do it this way too. Enabled by
default. @option{--no-escape-from-lines} disables this option.
-@item --passphrase-repeat @code{n}
+@item --passphrase-repeat @var{n}
@opindex passphrase-repeat
Specify how many times @command{@gpgname} will request a new
passphrase be repeated. This is useful for helping memorize a
passphrase. Defaults to 1 repetition.
-@item --passphrase-fd @code{n}
+@item --passphrase-fd @var{n}
@opindex passphrase-fd
-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},
+Read the passphrase from file descriptor @var{n}. Only the first line
+will be read from file descriptor @var{n}. If you use 0 for @var{n},
the passphrase will be read from STDIN. This can only be used if only
one passphrase is supplied.
Note that this passphrase is only used if the option @option{--batch}
has also been given. This is different from GnuPG version 1.x.
-@item --passphrase-file @code{file}
+@item --passphrase-file @var{file}
@opindex passphrase-file
-Read the passphrase from file @code{file}. Only the first line will
-be read from file @code{file}. This can only be used if only one
+Read the passphrase from file @var{file}. Only the first line will
+be read from file @var{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.
Note that this passphrase is only used if the option @option{--batch}
has also been given. This is different from GnuPG version 1.x.
-@item --passphrase @code{string}
+@item --passphrase @var{string}
@opindex passphrase
-Use @code{string} as the passphrase. This can only be used if only one
+Use @var{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.
Note that this passphrase is only used if the option @option{--batch}
has also been given. This is different from GnuPG version 1.x.
-@item --pinentry-mode @code{mode}
+@item --pinentry-mode @var{mode}
@opindex pinentry-mode
-Set the pinentry mode to @code{mode}. Allowed values for @code{mode}
+Set the pinentry mode to @var{mode}. Allowed values for @var{mode}
are:
@table @asis
@item default
@@ -3084,7 +3117,7 @@ are:
Pinentry the user is not prompted again if he enters a bad password.
@end table
-@item --command-fd @code{n}
+@item --command-fd @var{n}
@opindex command-fd
This is a replacement for the deprecated shared-memory IPC mode.
If this option is enabled, user input on questions is not expected
@@ -3092,10 +3125,10 @@ from the TTY but from the given file descriptor. It should be used
together with @option{--status-fd}. See the file doc/DETAILS in the source
distribution for details on how to use it.
-@item --command-file @code{file}
+@item --command-file @var{file}
@opindex command-file
Same as @option{--command-fd}, except the commands are read out of file
-@code{file}
+@var{file}
@item --allow-non-selfsigned-uid
@itemx --no-allow-non-selfsigned-uid
@@ -3150,7 +3183,7 @@ allows the verification of signatures made with such weak algorithms.
MD5 is the only digest algorithm considered weak by default. See also
@option{--weak-digest} to reject other digest algorithms.
-@item --weak-digest @code{name}
+@item --weak-digest @var{name}
@opindex weak-digest
Treat the specified digest algorithm as weak. Signatures made over
weak digests algorithms are normally rejected. This option can be
@@ -3215,12 +3248,12 @@ messaging system that the ciphertext transmitted corresponds to an
inappropriate plaintext so they can take action against the offending
user.
-@item --override-session-key @code{string}
-@itemx --override-session-key-fd @code{fd}
+@item --override-session-key @var{string}
+@itemx --override-session-key-fd @var{fd}
@opindex override-session-key
-Don't use the public key but the session key @code{string} respective
+Don't use the public key but the session key @var{string} respective
the session key taken from the first line read from file descriptor
-@code{fd}. The format of this string is the same as the one printed
+@var{fd}. The format of this string is the same as the one printed
by @option{--show-session-key}. This option is normally not used but
comes handy in case someone forces you to reveal the content of an
encrypted message; using this option you can do this without handing
@@ -3299,15 +3332,15 @@ Experimental use only.
Don't change the permissions of a secret keyring back to user
read/write only. Use this option only if you really know what you are doing.
-@item --default-preference-list @code{string}
+@item --default-preference-list @var{string}
@opindex default-preference-list
-Set the list of default preferences to @code{string}. This preference
+Set the list of default preferences to @var{string}. This preference
list is used for new keys and becomes the default for "setpref" in the
edit menu.
-@item --default-keyserver-url @code{name}
+@item --default-keyserver-url @var{name}
@opindex default-keyserver-url
-Set the default keyserver URL to @code{name}. This keyserver will be
+Set the default keyserver URL to @var{name}. This keyserver will be
used as the keyserver URL when writing a new self-signature on a key,
which includes key generation and changing preferences.
@@ -3777,7 +3810,7 @@ may be recoverable from it later.
Before you report a bug you should first search the mailing list
archives for similar problems and second check whether such a bug has
-already been reported to our bug tracker at http://bugs.gnupg.org .
+already been reported to our bug tracker at @url{https://bugs.gnupg.org}.
@c *******************************************
@c *************** **************
@@ -3861,7 +3894,7 @@ follows:
@item Text only, line length is limited to about 1000 characters.
@item UTF-8 encoding must be used to specify non-ASCII characters.
@item Empty lines are ignored.
- @item Leading and trailing while space is ignored.
+ @item Leading and trailing white space is ignored.
@item A hash sign as the first non white space character indicates
a comment line.
@item Control statements are indicated by a leading percent sign, the
diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi
index c3f5aac..5d79ce5 100644
--- a/doc/gpgsm.texi
+++ b/doc/gpgsm.texi
@@ -365,10 +365,7 @@ default value is @file{@value{BINDIR}/dirmngr}.
@item --prefer-system-dirmngr
@opindex prefer-system-dirmngr
-If a system wide @command{dirmngr} is running in daemon mode, first try
-to connect to this one. Fallback to a pipe based server if this does
-not work. Under Windows this option is ignored because the system dirmngr is
-always used.
+This option is obsolete and ignored.
@item --disable-dirmngr
Entirely disable the use of the Dirmngr.
@@ -564,7 +561,7 @@ Write output to @var{file}. The default is to write it to stdout.
Displays extra information with the @code{--list-keys} commands. Especially
a line tagged @code{grp} is printed which tells you the keygrip of a
key. This string is for example used as the file name of the
-secret key.
+secret key. Implies @code{--with-colons}.
@anchor{gpgsm-option --with-validation}
@item --with-validation
diff --git a/doc/tools.texi b/doc/tools.texi
index bdef6a2..d05018b 100644
--- a/doc/tools.texi
+++ b/doc/tools.texi
@@ -1160,6 +1160,8 @@ useful for unattended machines, where the usual @command{pinentry} tool
may not be used and the passphrases for the to be used keys are given at
machine startup.
+This program works with GnuPG 2 and later. GnuPG 1.x is not supported.
+
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
diff --git a/doc/wks.texi b/doc/wks.texi
new file mode 100644
index 0000000..f9b1a0c
--- /dev/null
+++ b/doc/wks.texi
@@ -0,0 +1,340 @@
+@c wks.texi - man pages for the Web Key Service tools.
+@c Copyright (C) 2017 g10 Code GmbH
+@c Copyright (C) 2017 Bundesamt für Sicherheit in der Informationstechnik
+@c This is part of the GnuPG manual.
+@c For copying conditions, see the file GnuPG.texi.
+
+@include defs.inc
+
+@node Web Key Service
+@chapter Web Key Service
+
+GnuPG comes with tools used to maintain and access a Web Key
+Directory.
+
+@menu
+* gpg-wks-client:: Send requests via WKS
+* gpg-wks-server:: Server to provide the WKS.
+@end menu
+
+@c
+@c GPG-WKS-CLIENT
+@c
+@manpage gpg-wks-client.1
+@node gpg-wks-client
+@section Send requests via WKS
+@ifset manverb
+.B gpg-wks-client
+\- Client for the Web Key Service
+@end ifset
+
+@mansect synopsis
+@ifset manverb
+.B gpg-wks-client
+.RI [ options ]
+.B \-\-supported
+.I user-id
+.br
+.B gpg-wks-client
+.RI [ options ]
+.B \-\-check
+.I user-id
+.br
+.B gpg-wks-client
+.RI [ options ]
+.B \-\-create
+.I fingerprint
+.I user-id
+.br
+.B gpg-wks-client
+.RI [ options ]
+.B \-\-receive
+.br
+.B gpg-wks-client
+.RI [ options ]
+.B \-\-read
+@end ifset
+
+@mansect description
+The @command{gpg-wks-client} is used to send requests to a Web Key
+Service provider. This is usuallay done to upload a key into a Web
+Key Directory.
+
+With the @option{--supported} command the caller can test whether a
+site supports the Web Key Service. The argument is an arbitray
+address in the to be tested domain. For example
+@file{foo@@example.net}. The command returns success if the Web Key
+Service is supported. The operation is silent; to get diagnostic
+output use the option @option{--verbose}.
+
+With the @option{--check} command the caller can test whether a key
+exists for a supplied mail address. The command returns success if a
+key is available.
+
+The @option{--create} command is used to send a request for
+publication in the Web Key Directory. The arguments are the
+fingerprint of the key and the user id to publish. The output from
+the command is a properly formatted mail with all standard headers.
+This mail can be fed to @command{sendmail(8)} or any other tool to
+actually send that mail. If @command{sendmail(8)} is installed the
+option @option{--send} can be used to directly send the created
+request.
+
+The @option{--receive} and @option{--read} commands are used to
+process confirmation mails as send from the service provider. The
+former expects an encrypted MIME messages, the latter an already
+decrypted MIME message. The result of these commands are another mail
+which can be send in the same way as the mail created with
+@option{--create}.
+
+@command{gpg-wks-client} is not commonly invoked directly and thus it
+is not installed in the bin directory. Here is an example how it can
+be invoked manually to check for a Web Key Directory entry for
+@file{foo@@example.org}:
+
+@example
+$(gpgconf --list-dirs libexecdir)/gpg-wks-client --check foo@@example.net
+@end example
+
+@mansect options
+@noindent
+@command{gpg-wks-client} understands these options:
+
+@table @gnupgtabopt
+
+@item --send
+@opindex send
+Directly send created mails using the @command{sendmail} command.
+Requires installation of that command.
+
+@item --output @var{file}
+@itemx -o
+@opindex output
+Write the created mail to @var{file} instead of stdout. Note that the
+value @code{-} for @var{file} is the same as writing to stdout.
+
+@item --status-fd @var{n}
+@opindex status-fd
+Write special status strings to the file descriptor @var{n}.
+This program returns only the status messages SUCCESS or FAILURE which
+are helpful when the caller uses a double fork approach and can't
+easily get the return code of the process.
+
+@item --verbose
+@opindex verbose
+Enable extra informational output.
+
+@item --quiet
+@opindex quiet
+Disable almost all informational output.
+
+@item --version
+@opindex version
+Print version of the program and exit.
+
+@item --help
+@opindex help
+Display a brief help page and exit.
+
+@end table
+
+
+@mansect see also
+@ifset isman
+@command{gpg-wks-server}(1)
+@end ifset
+
+
+@c
+@c GPG-WKS-SERVER
+@c
+@manpage gpg-wks-server.1
+@node gpg-wks-server
+@section Provide the Web Key Service
+@ifset manverb
+.B gpg-wks-server
+\- Server providing the Web Key Service
+@end ifset
+
+@mansect synopsis
+@ifset manverb
+.B gpg-wks-server
+.RI [ options ]
+.B \-\-receive
+.br
+.B gpg-wks-server
+.RI [ options ]
+.B \-\-cron
+.br
+.B gpg-wks-server
+.RI [ options ]
+.B \-\-list-domains
+.br
+.B gpg-wks-server
+.RI [ options ]
+.B \-\-install-key
+.I file
+.br
+.B gpg-wks-server
+.RI [ options ]
+.B \-\-remove-key
+.I mailaddr
+.br
+.B gpg-wks-server
+.RI [ options ]
+.B \-\-revoke-key
+.I mailaddr
+@end ifset
+
+@mansect description
+The @command{gpg-wks-server} is a server site implementation of the
+Web Key Service. It receives requests for publication, sends
+confirmation requests, receives confirmations, and published the key.
+It also has features to ease the setup and maintenance of a Web Key
+Directory.
+
+When used with the command @option{--receive} a single Web Key Service
+mail is processed. Commonly this command is used with the option
+@option{--send} to directly send the crerated mails back. See below
+for an installation example.
+
+The command @option{--cron} is used for regualr cleanup tasks. For
+example non-confirmed requested should be removed after their expire
+time. It is best to run this command once a day from a cronjob.
+
+The command @option{--list-domains} prints all configured domains.
+Further it creates missing directories for the configuration and
+prints warnings pertaining to problems in the configuration.
+
+The commands @option{--install-key}, @option{--remove-key}, and
+@option{--revoke-key} are not yet functional.
+
+
+@mansect options
+@noindent
+@command{gpg-wks-server} understands these options:
+
+@table @gnupgtabopt
+
+@item --from @var{mailaddr}
+@opindex from
+Use @var{mailaddr} as the default sender address.
+
+@item --header @var{name}=@var{value}
+@opindex header
+Add the mail header "@var{name}: @var{value}" to all outgoing mails.
+
+@item --send
+@opindex send
+Directly send created mails using the @command{sendmail} command.
+Requires installation of that command.
+
+@item --output @var{file}
+@itemx -o
+@opindex output
+Write the created mail also to @var{file}. Note that the value
+@code{-} for @var{file} would write it to stdout.
+
+@item --verbose
+@opindex verbose
+Enable extra informational output.
+
+@item --quiet
+@opindex quiet
+Disable almost all informational output.
+
+@item --version
+@opindex version
+Print version of the program and exit.
+
+@item --help
+@opindex help
+Display a brief help page and exit.
+
+@end table
+
+@noindent
+@mansect examples
+@chapheading Examples
+
+The Web Key Service requires a working directory to store keys
+pending for publication. As root create a working directory:
+
+@example
+ # mkdir /var/lib/gnupg/wks
+ # chown webkey:webkey /var/lib/gnupg/wks
+ # chmod 2750 /var/lib/gnupg/wks
+@end example
+
+Then under your webkey account create directories for all your
+domains. Here we do it for "example.net":
+
+@example
+ $ mkdir /var/lib/gnupg/wks/example.net
+@end example
+
+Finally run
+
+@example
+ $ gpg-wks-server --list-domains
+@end example
+
+to create the required sub-directories with the permission set
+correctly. For each domain a submission address needs to be
+configured. All service mails are directed to that address. It can
+be the same address for all configured domains, for example:
+
+@example
+ $ cd /var/lib/gnupg/wks/example.net
+ $ echo key-submission@@example.net >submission-address
+@end example
+
+The protocol requires that the key to be published is sent with an
+encrypted mail to the service. Thus you need to create a key for
+the submission address:
+
+@example
+ $ gpg --batch --passphrase '' --quick-gen-key key-submission@@example.net
+ $ gpg --with-wkd-hash -K key-submission@@example.net
+@end example
+
+The output of the last command looks similar to this:
+
+@example
+ sec rsa2048 2016-08-30 [SC]
+ C0FCF8642D830C53246211400346653590B3795B
+ uid [ultimate] key-submission@@example.net
+ bxzcxpxk8h87z1k7bzk86xn5aj47intu@@example.net
+ ssb rsa2048 2016-08-30 [E]
+@end example
+
+Take the hash of the string "key-submission", which is
+"bxzcxpxk8h87z1k7bzk86xn5aj47intu" and manually publish that key:
+
+@example
+ $ gpg --export-options export-minimal --export \
+ > -o /var/lib/gnupg/wks/example.net/hu/bxzcxpxk8h87z1k7bzk86xn5aj47intu \
+ > key-submission@@example.new
+@end example
+
+Make sure that the created file is world readable.
+
+Finally that submission address needs to be redirected to a script
+running @command{gpg-wks-server}. The @command{procmail} command can
+be used for this: Redirect the submission address to the user "webkey"
+and put this into webkey's @file{.procmailrc}:
+
+@example
+:0
+* !^From: webkey@@example.net
+* !^X-WKS-Loop: webkey.example.net
+|gpg-wks-server -v --receive \
+ --header X-WKS-Loop=webkey.example.net \
+ --from webkey@@example.net --send
+@end example
+
+
+@mansect see also
+@ifset isman
+@command{gpg-wks-client}(1)
+@end ifset
diff --git a/doc/yat2m.c b/doc/yat2m.c
index 23fc6ba..c7bec33 100644
--- a/doc/yat2m.c
+++ b/doc/yat2m.c
@@ -1,5 +1,5 @@
/* yat2m.c - Yet Another Texi 2 Man converter
- * Copyright (C) 2005, 2013, 2015, 2016 g10 Code GmbH
+ * Copyright (C) 2005, 2013, 2015, 2016, 2017 g10 Code GmbH
* Copyright (C) 2006, 2008, 2011 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
@@ -16,6 +16,12 @@
* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
+/**********************************************
+ * Note: The canonical source of this tool **
+ * is part of libgpg-error and it **
+ * installs yat2m on the build system. **
+ **********************************************/
+
/*
This is a simple texinfo to man page converter. It needs some
special markup in th e texinfo and tries best to get a create man
@@ -1478,6 +1484,7 @@ int
main (int argc, char **argv)
{
int last_argc = -1;
+ const char *s;
opt_source = "GNU";
opt_release = "";
@@ -1611,6 +1618,11 @@ main (int argc, char **argv)
if (argc > 1)
die ("usage: " PGM " [OPTION] [FILE] (try --help for more information)\n");
+ /* Take care of supplied timestamp for reproducible builds. See
+ * https://reproducible-builds.org/specs/source-date-epoch/ */
+ if (!opt_date && (s = getenv ("SOURCE_DATE_EPOCH")) && *s)
+ opt_date = s;
+
/* Start processing. */
if (argc && strcmp (*argv, "-"))
{
diff --git a/g10/Makefile.am b/g10/Makefile.am
index 330d6c5..cc4ef5c 100644
--- a/g10/Makefile.am
+++ b/g10/Makefile.am
@@ -77,7 +77,7 @@ trust_source = trustdb.c trustdb.h tdbdump.c tdbio.c tdbio.h
endif
if USE_TOFU
-tofu_source = tofu.h tofu.c gpgsql.c gpgsql.h sqrtu32.c sqrtu32.h
+tofu_source = tofu.h tofu.c gpgsql.c gpgsql.h
else
tofu_source =
endif
@@ -150,10 +150,11 @@ gpg_sources = server.c \
call-agent.c call-agent.h \
trust.c $(trust_source) $(tofu_source) \
$(card_source) \
- exec.c exec.h
+ exec.c exec.h \
+ key-check.c key-check.h
gpg_SOURCES = gpg.c \
- keyedit.c \
+ keyedit.c keyedit.h \
$(gpg_sources)
gpgcompose_SOURCES = gpgcompose.c $(gpg_sources)
diff --git a/g10/build-packet.c b/g10/build-packet.c
index fa2674b..d4a1d6a 100644
--- a/g10/build-packet.c
+++ b/g10/build-packet.c
@@ -182,8 +182,8 @@ build_packet (IOBUF out, PACKET *pkt)
/* Build a packet and write it to the stream OUT. This variant also
- * writes the meta data using ring tyrust packets. Returns: 0 on
- * success or on aerror code. */
+ * writes the meta data using ring trust packets. Returns: 0 on
+ * success or on error code. */
gpg_error_t
build_packet_and_meta (iobuf_t out, PACKET *pkt)
{
@@ -213,7 +213,7 @@ build_packet_and_meta (iobuf_t out, PACKET *pkt)
PKT_user_id *uid = pkt->pkt.user_id;
rt.subtype = RING_TRUST_UID;
- rt.keysrc = uid->keysrc;
+ rt.keyorg = uid->keyorg;
rt.keyupdate = uid->keyupdate;
rt.url = uid->updateurl;
err = do_ring_trust (out, &rt);
@@ -225,7 +225,7 @@ build_packet_and_meta (iobuf_t out, PACKET *pkt)
PKT_public_key *pk = pkt->pkt.public_key;
rt.subtype = RING_TRUST_KEY;
- rt.keysrc = pk->keysrc;
+ rt.keyorg = pk->keyorg;
rt.keyupdate = pk->keyupdate;
rt.url = pk->updateurl;
err = do_ring_trust (out, &rt);
@@ -395,7 +395,7 @@ do_ring_trust (iobuf_t out, PKT_ring_trust *rt)
iobuf_put (out, rt->subtype);
if (rt->subtype == RING_TRUST_KEY || rt->subtype == RING_TRUST_UID)
{
- iobuf_put (out, rt->keysrc);
+ iobuf_put (out, rt->keyorg);
write_32 (out, rt->keyupdate);
iobuf_put (out, namelen);
if (namelen)
diff --git a/g10/call-agent.c b/g10/call-agent.c
index be8c33d..1ce6641 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -194,8 +194,10 @@ warn_version_mismatch (assuan_context_t ctx, const char *servername, int mode)
err = get_assuan_server_version (ctx, mode, &serverversion);
if (err)
- log_error (_("error getting version from '%s': %s\n"),
- servername, gpg_strerror (err));
+ log_log (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED?
+ GPGRT_LOG_INFO : GPGRT_LOG_ERROR,
+ _("error getting version from '%s': %s\n"),
+ servername, gpg_strerror (err));
else if (compare_version_strings (serverversion, myversion) < 0)
{
char *warn;
@@ -217,10 +219,12 @@ warn_version_mismatch (assuan_context_t ctx, const char *servername, int mode)
}
+#define FLAG_FOR_CARD_SUPPRESS_ERRORS 2
+
/* 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 (ctrl_t ctrl, int for_card)
+start_agent (ctrl_t ctrl, int flag_for_card)
{
int rc;
@@ -277,22 +281,41 @@ start_agent (ctrl_t ctrl, int for_card)
write_status_error ("set_pinentry_mode", rc);
}
}
+
+ /* In DE_VS mode under Windows we require that the JENT RNG
+ * is active. */
+#ifdef HAVE_W32_SYSTEM
+ if (!rc && opt.compliance == CO_DE_VS)
+ {
+ if (assuan_transact (agent_ctx, "GETINFO jent_active",
+ NULL, NULL, NULL, NULL, NULL, NULL))
+ {
+ rc = gpg_error (GPG_ERR_FORBIDDEN);
+ log_error (_("%s is not compliant with %s mode\n"),
+ GPG_AGENT_NAME,
+ gnupg_compliance_option_string (opt.compliance));
+ write_status_error ("random-compliance", rc);
+ }
+ }
+#endif /*HAVE_W32_SYSTEM*/
+
}
}
- if (!rc && for_card && !did_early_card_test)
+ if (!rc && flag_for_card && !did_early_card_test)
{
/* Request the serial number of the card for an early test. */
struct agent_card_info_s info;
memset (&info, 0, sizeof info);
- rc = warn_version_mismatch (agent_ctx, SCDAEMON_NAME, 2);
+ if (!(flag_for_card & FLAG_FOR_CARD_SUPPRESS_ERRORS))
+ rc = warn_version_mismatch (agent_ctx, SCDAEMON_NAME, 2);
if (!rc)
rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
NULL, NULL, NULL, NULL,
learn_status_cb, &info);
- if (rc)
+ if (rc && !(flag_for_card & FLAG_FOR_CARD_SUPPRESS_ERRORS))
{
switch (gpg_err_code (rc))
{
@@ -1023,7 +1046,7 @@ agent_scd_serialno (char **r_serialno, const char *demand)
char *serialno = NULL;
char line[ASSUAN_LINELENGTH];
- err = start_agent (NULL, 1);
+ err = start_agent (NULL, 1 | FLAG_FOR_CARD_SUPPRESS_ERRORS);
if (err)
return err;
@@ -2073,7 +2096,8 @@ inq_import_key_parms (void *opaque, const char *line)
/* 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, int force)
+ const void *key, size_t keylen, int unattended, int force,
+ u32 *keyid, u32 *mainkeyid, int pubkey_algo)
{
gpg_error_t err;
struct import_key_parm_s parm;
@@ -2083,6 +2107,9 @@ agent_import_key (ctrl_t ctrl, const char *desc, char **cache_nonce_addr,
memset (&dfltparm, 0, sizeof dfltparm);
dfltparm.ctrl = ctrl;
+ dfltparm.keyinfo.keyid = keyid;
+ dfltparm.keyinfo.mainkeyid = mainkeyid;
+ dfltparm.keyinfo.pubkey_algo = pubkey_algo;
err = start_agent (ctrl, 0);
if (err)
@@ -2129,7 +2156,8 @@ agent_import_key (ctrl_t ctrl, const char *desc, char **cache_nonce_addr,
gpg_error_t
agent_export_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
int openpgp_protected, char **cache_nonce_addr,
- unsigned char **r_result, size_t *r_resultlen)
+ unsigned char **r_result, size_t *r_resultlen,
+ u32 *keyid, u32 *mainkeyid, int pubkey_algo)
{
gpg_error_t err;
struct cache_nonce_parm_s cn_parm;
@@ -2141,6 +2169,9 @@ agent_export_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
memset (&dfltparm, 0, sizeof dfltparm);
dfltparm.ctrl = ctrl;
+ dfltparm.keyinfo.keyid = keyid;
+ dfltparm.keyinfo.mainkeyid = mainkeyid;
+ dfltparm.keyinfo.pubkey_algo = pubkey_algo;
*r_result = NULL;
diff --git a/g10/call-agent.h b/g10/call-agent.h
index a04fc73..f45b64d 100644
--- a/g10/call-agent.h
+++ b/g10/call-agent.h
@@ -186,13 +186,15 @@ gpg_error_t agent_keywrap_key (ctrl_t ctrl, int forexport,
/* 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, int force);
+ size_t keylen, int unattended, int force,
+ u32 *keyid, u32 *mainkeyid, int pubkey_algo);
/* Receive a key from the agent. */
gpg_error_t agent_export_key (ctrl_t ctrl, const char *keygrip,
const char *desc, int openpgp_protected,
char **cache_nonce_addr,
- unsigned char **r_result, size_t *r_resultlen);
+ unsigned char **r_result, size_t *r_resultlen,
+ u32 *keyid, u32 *mainkeyid, int pubkey_algo);
/* Delete a key from the agent. */
gpg_error_t agent_delete_key (ctrl_t ctrl, const char *hexkeygrip,
diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c
index cb6c69c..9bae59f 100644
--- a/g10/call-dirmngr.c
+++ b/g10/call-dirmngr.c
@@ -41,7 +41,8 @@
#include "call-dirmngr.h"
-/* Parameter structure used to gather status info. */
+/* Parameter structure used to gather status info. Note that it is
+ * also used for WKD requests. */
struct ks_status_parm_s
{
const char *keyword; /* Look for this keyword or NULL for "SOURCE". */
@@ -368,7 +369,7 @@ clear_context_flags (ctrl_t ctrl, assuan_context_t ctx)
-/* Status callback for ks_list, ks_get and ks_search. */
+/* Status callback for ks_list, ks_get, ks_search, and wkd_get */
static gpg_error_t
ks_status_cb (void *opaque, const char *line)
{
@@ -379,6 +380,7 @@ ks_status_cb (void *opaque, const char *line)
if ((s = has_leading_keyword (line, parm->keyword? parm->keyword : "SOURCE")))
{
+ /* Note that the arg for "S SOURCE" is the URL of a keyserver. */
if (!parm->source)
{
parm->source = xtrystrdup (s);
@@ -1316,17 +1318,24 @@ gpg_dirmngr_get_pka (ctrl_t ctrl, const char *userid,
/* Ask the dirmngr to retrieve a key via the Web Key Directory
* protocol. If QUICK is set the dirmngr is advised to use a shorter
- * timeout. On success a new estream with the key is stored at R_KEY.
+ * timeout. On success a new estream with the key stored at R_KEY and the
+ * url of the lookup (if any) stored at R_URL. Note that
*/
gpg_error_t
-gpg_dirmngr_wkd_get (ctrl_t ctrl, const char *name, int quick, estream_t *r_key)
+gpg_dirmngr_wkd_get (ctrl_t ctrl, const char *name, int quick,
+ estream_t *r_key, char **r_url)
{
gpg_error_t err;
assuan_context_t ctx;
- struct dns_cert_parm_s parm;
+ struct ks_status_parm_s stparm = { NULL };
+ struct dns_cert_parm_s parm = { NULL };
char *line = NULL;
- memset (&parm, 0, sizeof parm);
+ if (r_key)
+ *r_key = NULL;
+
+ if (r_url)
+ *r_url = NULL;
err = open_context (ctrl, &ctx);
if (err)
@@ -1351,7 +1360,7 @@ gpg_dirmngr_wkd_get (ctrl_t ctrl, const char *name, int quick, estream_t *r_key)
goto leave;
}
err = assuan_transact (ctx, line, dns_cert_data_cb, &parm,
- NULL, NULL, NULL, &parm);
+ NULL, NULL, ks_status_cb, &stparm);
if (err)
goto leave;
@@ -1362,7 +1371,14 @@ gpg_dirmngr_wkd_get (ctrl_t ctrl, const char *name, int quick, estream_t *r_key)
parm.memfp = NULL;
}
+ if (r_url)
+ {
+ *r_url = stparm.source;
+ stparm.source = NULL;
+ }
+
leave:
+ xfree (stparm.source);
xfree (parm.fpr);
xfree (parm.url);
es_fclose (parm.memfp);
diff --git a/g10/call-dirmngr.h b/g10/call-dirmngr.h
index 95a8c4a..285c4cb 100644
--- a/g10/call-dirmngr.h
+++ b/g10/call-dirmngr.h
@@ -41,7 +41,7 @@ gpg_error_t gpg_dirmngr_get_pka (ctrl_t ctrl, const char *userid,
unsigned char **r_fpr, size_t *r_fprlen,
char **r_url);
gpg_error_t gpg_dirmngr_wkd_get (ctrl_t ctrl, const char *name, int quick,
- estream_t *r_key);
+ estream_t *r_key, char **r_url);
#endif /*GNUPG_G10_CALL_DIRMNGR_H*/
diff --git a/g10/card-util.c b/g10/card-util.c
index 78cd52b..62b2a67 100644
--- a/g10/card-util.c
+++ b/g10/card-util.c
@@ -777,14 +777,6 @@ change_url (void)
trim_spaces (url);
cpr_kill_prompt ();
- if (strlen (url) > 254 )
- {
- tty_printf (_("Error: URL too long "
- "(limit is %d characters).\n"), 254);
- xfree (url);
- return -1;
- }
-
rc = agent_scd_setattr ("PUBKEY-URL", url, strlen (url), NULL );
if (rc)
log_error ("error setting URL: %s\n", gpg_strerror (rc));
@@ -818,7 +810,7 @@ fetch_url (ctrl_t ctrl)
strlist_t sl = NULL;
add_to_strlist (&sl, info.pubkey_url);
- rc = keyserver_fetch (ctrl, sl);
+ rc = keyserver_fetch (ctrl, sl, KEYORG_URL);
free_strlist (sl);
}
else if (info.fpr1valid)
@@ -831,12 +823,14 @@ fetch_url (ctrl_t ctrl)
}
-/* Read data from file FNAME up to MAXLEN characters. On error return
- -1 and store NULL at R_BUFFER; on success return the number of
- bytes read and store the address of a newly allocated buffer at
- R_BUFFER. */
+#define MAX_GET_DATA_FROM_FILE 16384
+
+/* Read data from file FNAME up to MAX_GET_DATA_FROM_FILE characters.
+ On error return -1 and store NULL at R_BUFFER; on success return
+ the number of bytes read and store the address of a newly allocated
+ buffer at R_BUFFER. */
static int
-get_data_from_file (const char *fname, size_t maxlen, char **r_buffer)
+get_data_from_file (const char *fname, char **r_buffer)
{
estream_t fp;
char *data;
@@ -859,7 +853,7 @@ get_data_from_file (const char *fname, size_t maxlen, char **r_buffer)
return -1;
}
- data = xtrymalloc (maxlen? maxlen:1);
+ data = xtrymalloc (MAX_GET_DATA_FROM_FILE);
if (!data)
{
tty_printf (_("error allocating enough memory: %s\n"), strerror (errno));
@@ -867,10 +861,7 @@ get_data_from_file (const char *fname, size_t maxlen, char **r_buffer)
return -1;
}
- if (maxlen)
- n = es_fread (data, 1, maxlen, fp);
- else
- n = 0;
+ n = es_fread (data, 1, MAX_GET_DATA_FROM_FILE, fp);
es_fclose (fp);
if (n < 0)
{
@@ -927,7 +918,7 @@ change_login (const char *args)
{
for (args++; spacep (args); args++)
;
- n = get_data_from_file (args, 254, &data);
+ n = get_data_from_file (args, &data);
if (n < 0)
return -1;
}
@@ -942,14 +933,6 @@ change_login (const char *args)
n = strlen (data);
}
- if (n > 254 )
- {
- tty_printf (_("Error: Login data too long "
- "(limit is %d characters).\n"), 254);
- xfree (data);
- return -1;
- }
-
rc = agent_scd_setattr ("LOGIN-DATA", data, n, NULL );
if (rc)
log_error ("error setting login data: %s\n", gpg_strerror (rc));
@@ -973,7 +956,7 @@ change_private_do (const char *args, int nr)
{
for (args++; spacep (args); args++)
;
- n = get_data_from_file (args, 254, &data);
+ n = get_data_from_file (args, &data);
if (n < 0)
return -1;
}
@@ -988,14 +971,6 @@ change_private_do (const char *args, int nr)
n = strlen (data);
}
- if (n > 254 )
- {
- tty_printf (_("Error: Private DO too long "
- "(limit is %d characters).\n"), 254);
- xfree (data);
- return -1;
- }
-
rc = agent_scd_setattr (do_name, data, n, NULL );
if (rc)
log_error ("error setting private DO: %s\n", gpg_strerror (rc));
@@ -1016,7 +991,7 @@ change_cert (const char *args)
{
for (args++; spacep (args); args++)
;
- n = get_data_from_file (args, 16384, &data);
+ n = get_data_from_file (args, &data);
if (n < 0)
return -1;
}
diff --git a/g10/cpr.c b/g10/cpr.c
index 3391071..1548720 100644
--- a/g10/cpr.c
+++ b/g10/cpr.c
@@ -73,7 +73,7 @@ status_currently_allowed (int no)
return 1; /* Yes. */
/* We allow some statis anyway, so that import statistics are
- correct and to avoid problems if the retriebval subsystem will
+ correct and to avoid problems if the retrieval subsystem will
prompt the user. */
switch (no)
{
diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c
index 96e2487..736534d 100644
--- a/g10/decrypt-data.c
+++ b/g10/decrypt-data.c
@@ -29,6 +29,7 @@
#include "options.h"
#include "../common/i18n.h"
#include "../common/status.h"
+#include "../common/compliance.h"
static int mdc_decode_filter ( void *opaque, int control, IOBUF a,
@@ -97,6 +98,17 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
dek->algo_info_printed = 1;
}
+ /* Check compliance. */
+ if (! gnupg_cipher_is_allowed (opt.compliance, 0, dek->algo,
+ GCRY_CIPHER_MODE_CFB))
+ {
+ log_error (_("cipher algorithm '%s' may not be used in %s mode\n"),
+ openpgp_cipher_algo_name (dek->algo),
+ gnupg_compliance_option_string (opt.compliance));
+ rc = gpg_error (GPG_ERR_CIPHER_ALGO);
+ goto leave;
+ }
+
{
char buf[20];
diff --git a/g10/encrypt.c b/g10/encrypt.c
index 57ac8ad..c68d6d5 100644
--- a/g10/encrypt.c
+++ b/g10/encrypt.c
@@ -38,6 +38,7 @@
#include "../common/i18n.h"
#include "../common/status.h"
#include "pkglue.h"
+#include "../common/compliance.h"
static int encrypt_simple( const char *filename, int mode, int use_seskey );
@@ -184,6 +185,16 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
progress_filter_context_t *pfx;
int do_compress = !!default_compress_algo();
+ if (!gnupg_rng_is_compliant (opt.compliance))
+ {
+ rc = gpg_error (GPG_ERR_FORBIDDEN);
+ log_error (_("%s is not compliant with %s mode\n"),
+ "RNG",
+ gnupg_compliance_option_string (opt.compliance));
+ write_status_error ("random-compliance", rc);
+ return rc;
+ }
+
pfx = new_progress_context ();
memset( &cfx, 0, sizeof cfx);
memset( &zfx, 0, sizeof zfx);
@@ -485,6 +496,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
progress_filter_context_t *pfx;
PK_LIST pk_list;
int do_compress;
+ int compliant;
if (filefd != -1 && filename)
return gpg_error (GPG_ERR_INV_ARG); /* Both given. */
@@ -612,6 +624,58 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
cfx.dek->algo = opt.def_cipher_algo;
}
+ /* Check compliance. */
+ if (! gnupg_cipher_is_allowed (opt.compliance, 1, cfx.dek->algo,
+ GCRY_CIPHER_MODE_CFB))
+ {
+ log_error (_("cipher algorithm '%s' may not be used in %s mode\n"),
+ openpgp_cipher_algo_name (cfx.dek->algo),
+ gnupg_compliance_option_string (opt.compliance));
+ rc = gpg_error (GPG_ERR_CIPHER_ALGO);
+ goto leave;
+ }
+
+ if (!gnupg_rng_is_compliant (opt.compliance))
+ {
+ rc = gpg_error (GPG_ERR_FORBIDDEN);
+ log_error (_("%s is not compliant with %s mode\n"),
+ "RNG",
+ gnupg_compliance_option_string (opt.compliance));
+ write_status_error ("random-compliance", rc);
+ goto leave;
+ }
+
+ compliant = gnupg_cipher_is_compliant (CO_DE_VS, cfx.dek->algo,
+ GCRY_CIPHER_MODE_CFB);
+
+ {
+ pk_list_t pkr;
+
+ for (pkr = pk_list; pkr; pkr = pkr->next)
+ {
+ PKT_public_key *pk = pkr->pk;
+ unsigned int nbits = nbits_from_pk (pk);
+
+ if (!gnupg_pk_is_compliant (opt.compliance,
+ pk->pubkey_algo, pk->pkey, nbits, NULL))
+ log_info (_("WARNING: key %s is not suitable for encryption"
+ " in %s mode\n"),
+ keystr_from_pk (pk),
+ gnupg_compliance_option_string (opt.compliance));
+
+ if (compliant
+ && !gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, pk->pkey,
+ nbits, NULL))
+ compliant = 0;
+ }
+
+ }
+
+ if (compliant)
+ write_status_strings (STATUS_ENCRYPTION_COMPLIANCE_MODE,
+ gnupg_status_compliance_flag (CO_DE_VS),
+ NULL);
+
cfx.dek->use_mdc = use_mdc (pk_list,cfx.dek->algo);
/* Only do the is-file-already-compressed check if we are using a
@@ -931,8 +995,9 @@ write_pubkey_enc_from_list (ctrl_t ctrl, PK_LIST pk_list, DEK *dek, iobuf_t out)
{
if (opt.throw_keyids && (PGP6 || PGP7 || PGP8))
{
- log_info(_("you may not use %s while in %s mode\n"),
- "--throw-keyids",compliance_option_string());
+ log_info(_("option '%s' may not be used in %s mode\n"),
+ "--throw-keyids",
+ gnupg_compliance_option_string (opt.compliance));
compliance_failure();
}
diff --git a/g10/export.c b/g10/export.c
index ce79a2f..8f6371b 100644
--- a/g10/export.c
+++ b/g10/export.c
@@ -1190,7 +1190,8 @@ receive_seckey_from_agent (ctrl_t ctrl, gcry_cipher_hd_t cipherhd,
prompt = gpg_format_keydesc (ctrl, pk, FORMAT_KEYDESC_EXPORT,1);
err = agent_export_key (ctrl, hexgrip, prompt, !cleartext, cache_nonce_addr,
- &wrappedkey, &wrappedkeylen);
+ &wrappedkey, &wrappedkeylen,
+ pk->keyid, pk->main_keyid, pk->pubkey_algo);
xfree (prompt);
if (err)
diff --git a/g10/free-packet.c b/g10/free-packet.c
index cd222a2..e15ad3f 100644
--- a/g10/free-packet.c
+++ b/g10/free-packet.c
@@ -224,6 +224,12 @@ copy_public_key (PKT_public_key *d, PKT_public_key *s)
}
else
d->revkey = NULL;
+
+ if (s->serialno)
+ d->serialno = xstrdup (s->serialno);
+ if (s->updateurl)
+ d->updateurl = xstrdup (s->updateurl);
+
return d;
}
diff --git a/g10/getkey.c b/g10/getkey.c
index d8c81c9..79bce61 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -1583,31 +1583,30 @@ pubkey_cmp (ctrl_t ctrl, const char *name, struct pubkey_cmp_cookie *old,
/* This function works like get_pubkey_byname, but if the name
* resembles a mail address, the results are ranked and only the best
* result is returned. */
-int
+gpg_error_t
get_best_pubkey_byname (ctrl_t ctrl, GETKEY_CTX *retctx, PKT_public_key *pk,
const char *name, KBNODE *ret_keyblock,
int include_unusable, int no_akl)
{
- int rc;
+ gpg_error_t err;
struct getkey_ctx_s *ctx = NULL;
if (retctx)
*retctx = NULL;
- rc = get_pubkey_byname (ctrl, &ctx, pk, name, ret_keyblock,
- NULL, include_unusable, no_akl);
- if (rc)
+ err = get_pubkey_byname (ctrl, &ctx, pk, name, ret_keyblock,
+ NULL, include_unusable, no_akl);
+ if (err)
{
- if (ctx)
- getkey_end (ctrl, ctx);
- return rc;
+ getkey_end (ctrl, ctx);
+ return err;
}
if (is_valid_mailbox (name) && ctx)
{
/* Rank results and return only the most relevant key. */
struct pubkey_cmp_cookie best = { 0 };
- struct pubkey_cmp_cookie new;
+ struct pubkey_cmp_cookie new = { 0 };
kbnode_t new_keyblock;
while (getkey_next (ctrl, ctx, &new.key, &new_keyblock) == 0)
@@ -1647,16 +1646,17 @@ get_best_pubkey_byname (ctrl_t ctrl, GETKEY_CTX *retctx, PKT_public_key *pk,
{
ctx = xtrycalloc (1, sizeof **retctx);
if (! ctx)
- rc = gpg_error_from_syserror ();
+ err = gpg_error_from_syserror ();
else
{
ctx->kr_handle = keydb_new ();
if (! ctx->kr_handle)
{
+ err = gpg_error_from_syserror ();
xfree (ctx);
+ ctx = NULL;
if (retctx)
*retctx = NULL;
- rc = gpg_error_from_syserror ();
}
else
{
@@ -1671,7 +1671,7 @@ get_best_pubkey_byname (ctrl_t ctrl, GETKEY_CTX *retctx, PKT_public_key *pk,
{
release_kbnode (*ret_keyblock);
*ret_keyblock = NULL;
- rc = getkey_next (ctrl, ctx, NULL, ret_keyblock);
+ err = getkey_next (ctrl, ctx, NULL, ret_keyblock);
}
}
}
@@ -1684,7 +1684,7 @@ get_best_pubkey_byname (ctrl_t ctrl, GETKEY_CTX *retctx, PKT_public_key *pk,
}
}
- if (rc && ctx)
+ if (err && ctx)
{
getkey_end (ctrl, ctx);
ctx = NULL;
@@ -1695,7 +1695,7 @@ get_best_pubkey_byname (ctrl_t ctrl, GETKEY_CTX *retctx, PKT_public_key *pk,
else
getkey_end (ctrl, ctx);
- return rc;
+ return err;
}
@@ -2219,10 +2219,27 @@ getkey_end (ctrl_t ctrl, getkey_ctx_t ctx)
{
if (ctx)
{
+#ifdef HAVE_W32_SYSTEM
+
+ /* FIXME: This creates a big regression for Windows because the
+ * keyring is only released after the global ctrl is released.
+ * So if an operation does a getkey and then tries to modify the
+ * keyring it will fail on Windows with a sharing violation. We
+ * need to modify all keyring write operations to also take the
+ * ctrl and close the cached_getkey_kdb handle to make writing
+ * work. See: GnuPG-bug-id: 3097 */
+ (void)ctrl;
+ keydb_release (ctx->kr_handle);
+
+#else /*!HAVE_W32_SYSTEM*/
+
if (ctrl && !ctrl->cached_getkey_kdb)
ctrl->cached_getkey_kdb = ctx->kr_handle;
else
keydb_release (ctx->kr_handle);
+
+#endif /*!HAVE_W32_SYSTEM*/
+
free_strlist (ctx->extra_list);
if (!ctx->not_allocated)
xfree (ctx);
@@ -2474,32 +2491,32 @@ sig_to_revoke_info (PKT_signature * sig, struct revoke_info *rinfo)
/* Given a keyblock, parse the key block and extract various pieces of
- information and save them with the primary key packet and the user
- id packets. For instance, some information is stored in signature
- packets. We find the latest such valid packet (since the user can
- change that information) and copy its contents into the
- PKT_public_key.
-
- Note that R_REVOKED may be set to 0, 1 or 2.
-
- This function fills in the following fields in the primary key's
- keyblock:
-
- main_keyid (computed)
- revkey / numrevkeys (derived from self signed key data)
- flags.valid (whether we have at least 1 self-sig)
- flags.maybe_revoked (whether a designed revoked the key, but
- we are missing the key to check the sig)
- selfsigversion (highest version of any valid self-sig)
- pubkey_usage (derived from most recent self-sig or most
- recent user id)
- has_expired (various sources)
- expiredate (various sources)
-
- See the documentation for fixup_uidnode for how the user id packets
- are modified. In addition to that the primary user id's is_primary
- field is set to 1 and the other user id's is_primary are set to
- 0. */
+ * information and save them with the primary key packet and the user
+ * id packets. For instance, some information is stored in signature
+ * packets. We find the latest such valid packet (since the user can
+ * change that information) and copy its contents into the
+ * PKT_public_key.
+ *
+ * Note that R_REVOKED may be set to 0, 1 or 2.
+ *
+ * This function fills in the following fields in the primary key's
+ * keyblock:
+ *
+ * main_keyid (computed)
+ * revkey / numrevkeys (derived from self signed key data)
+ * flags.valid (whether we have at least 1 self-sig)
+ * flags.maybe_revoked (whether a designed revoked the key, but
+ * we are missing the key to check the sig)
+ * selfsigversion (highest version of any valid self-sig)
+ * pubkey_usage (derived from most recent self-sig or most
+ * recent user id)
+ * has_expired (various sources)
+ * expiredate (various sources)
+ *
+ * See the documentation for fixup_uidnode for how the user id packets
+ * are modified. In addition to that the primary user id's is_primary
+ * field is set to 1 and the other user id's is_primary are set to 0.
+ */
static void
merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
struct revoke_info *rinfo)
@@ -2520,17 +2537,16 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
memset (rinfo, 0, sizeof (*rinfo));
/* Section 11.1 of RFC 4880 determines the order of packets within a
- message. There are three sections, which must occur in the
- following order: the public key, the user ids and user attributes
- and the subkeys. Within each section, each primary packet (e.g.,
- a user id packet) is followed by one or more signature packets,
- which modify that packet. */
+ * message. There are three sections, which must occur in the
+ * following order: the public key, the user ids and user attributes
+ * and the subkeys. Within each section, each primary packet (e.g.,
+ * a user id packet) is followed by one or more signature packets,
+ * which modify that packet. */
/* According to Section 11.1 of RFC 4880, the public key must be the
- first packet. */
+ first packet. Note that parse_keyblock_image ensures that the
+ first packet is the public key. */
if (keyblock->pkt->pkttype != PKT_PUBLIC_KEY)
- /* parse_keyblock_image ensures that the first packet is the
- public key. */
BUG ();
pk = keyblock->pkt->pkt.public_key;
keytimestamp = pk->timestamp;
@@ -2549,16 +2565,16 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
}
/* First pass:
-
- - Find the latest direct key self-signature. We assume that the
- newest one overrides all others.
-
- - Determine whether the key has been revoked.
-
- - Gather all revocation keys (unlike other data, we don't just
- take them from the latest self-signed packet).
-
- - Determine max (sig[...]->version).
+ *
+ * - Find the latest direct key self-signature. We assume that the
+ * newest one overrides all others.
+ *
+ * - Determine whether the key has been revoked.
+ *
+ * - Gather all revocation keys (unlike other data, we don't just
+ * take them from the latest self-signed packet).
+ *
+ * - Determine max (sig[...]->version).
*/
/* Reset this in case this key was already merged. */
@@ -2570,8 +2586,8 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
sigdate = 0; /* Helper variable to find the latest signature. */
/* According to Section 11.1 of RFC 4880, the public key comes first
- and is immediately followed by any signature packets that modify
- it. */
+ * and is immediately followed by any signature packets that modify
+ * it. */
for (k = keyblock;
k && k->pkt->pkttype != PKT_USER_ID
&& k->pkt->pkttype != PKT_ATTRIBUTE
@@ -2582,8 +2598,8 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
{
PKT_signature *sig = k->pkt->pkt.signature;
if (sig->keyid[0] == kid[0] && sig->keyid[1] == kid[1])
- /* Self sig. */
- {
+ { /* Self sig. */
+
if (check_key_signature (ctrl, keyblock, k, NULL))
; /* Signature did not verify. */
else if (IS_KEY_REV (sig))
@@ -2603,11 +2619,11 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
else if (IS_KEY_SIG (sig))
{
/* Add the indicated revocations keys from all
- signatures not just the latest. We do this
- because you need multiple 1F sigs to properly
- handle revocation keys (PGP does it this way, and
- a revocation key could be sensitive and hence in
- a different signature). */
+ * signatures not just the latest. We do this
+ * because you need multiple 1F sigs to properly
+ * handle 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;
@@ -2623,8 +2639,8 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
}
if (sig->timestamp >= sigdate)
- /* This is the latest signature so far. */
- {
+ { /* This is the latest signature so far. */
+
if (sig->flags.expired)
; /* Signature has expired - ignore it. */
else
@@ -2671,9 +2687,9 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
sizeof (struct revocation_key));
}
+ /* SIGNODE is the 1F signature packet with the latest creation time.
+ * Extract some information from it. */
if (signode)
- /* SIGNODE is the 1F signature packet with the latest creation
- time. Extract some information from it. */
{
/* Some information from a direct key signature take precedence
* over the same information given in UID sigs. */
@@ -2695,9 +2711,9 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
}
/* 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. */
+ * 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)
@@ -2715,20 +2731,20 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
*r_revoked = 2;
sig_to_revoke_info (sig, rinfo);
/* Don't continue checking since we can't be any
- more revoked than this. */
+ * more revoked than this. */
break;
}
else if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY)
pk->flags.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. */
+ * 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. */
+ /* Fixme: In the future handle subkey and cert
+ * revocations? PGP doesn't, but it's in 2440. */
}
}
}
@@ -2736,28 +2752,30 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
/* Second pass: Look at the self-signature of all user IDs. */
/* According to RFC 4880 section 11.1, user id and attribute packets
- are in the second section, after the public key packet and before
- the subkey packets. */
+ * are in the second section, after the public key packet and before
+ * the subkey packets. */
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 || k->pkt->pkttype == PKT_ATTRIBUTE)
- /* New user id packet. */
- {
+ { /* New user id packet. */
+
+ /* Apply the data from the most recent self-signed packet to
+ * the preceding user id packet. */
if (uidnode && signode)
- /* Apply the data from the most recent self-signed packet
- to the preceding user id packet. */
{
fixup_uidnode (uidnode, signode, keytimestamp);
pk->flags.valid = 1;
}
+
/* Clear SIGNODE. The only relevant self-signed data for
- UIDNODE follows it. */
+ * UIDNODE follows it. */
if (k->pkt->pkttype == PKT_USER_ID)
uidnode = k;
else
uidnode = NULL;
+
signode = NULL;
sigdate = 0;
}
@@ -2795,7 +2813,7 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
}
/* If the key isn't valid yet, and we have
- --allow-non-selfsigned-uid set, then force it valid. */
+ * --allow-non-selfsigned-uid set, then force it valid. */
if (!pk->flags.valid && opt.allow_non_selfsigned_uid)
{
if (opt.verbose)
@@ -2805,7 +2823,7 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
}
/* The key STILL isn't valid, so try and find an ultimately
- trusted signature. */
+ * trusted signature. */
if (!pk->flags.valid)
{
uidnode = NULL;
@@ -2825,12 +2843,11 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
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 the user should also remove the
- ultimate trust flag. */
+ /* 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 the user
+ * should also remove the ultimate trust flag. */
if (get_pubkey_fast (ultimate_pk, sig->keyid) == 0
&& check_key_signature2 (ctrl,
keyblock, k, ultimate_pk,
@@ -2848,20 +2865,18 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
}
}
- /* 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.) */
+ /* 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.
- */
+ /* Now that we had a look at all user IDs we can now get some
+ * information from those user IDs. */
if (!key_usage)
{
@@ -2873,6 +2888,7 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
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;
@@ -2881,6 +2897,7 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
}
}
}
+
if (!key_usage)
{
/* No key flags at all: get it from the algo. */
@@ -2919,7 +2936,7 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
}
/* Currently only v3 keys have a maximum expiration date, but I'll
- bet v5 keys get this feature again. */
+ * bet v5 keys get this feature again. */
if (key_expire == 0
|| (pk->max_expiredate && key_expire > pk->max_expiredate))
key_expire = pk->max_expiredate;
@@ -2927,8 +2944,8 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
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. */
+ /* 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;
@@ -2947,12 +2964,11 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
}
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. */
+ /* 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;
}
@@ -2989,14 +3005,14 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
else if (uidnode2)
{
/* None is flagged primary - use the latest user ID we have,
- and disambiguate with the arbitrary packet comparison. */
+ * and disambiguate with the arbitrary packet comparison. */
uidnode2->pkt->pkt.user_id->flags.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. */
+ * 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;
@@ -3022,16 +3038,19 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
uidnode->pkt->pkt.user_id->flags.primary = 1;
}
else
- k->pkt->pkt.user_id->flags.primary = 0; /* just to be
- safe */
+ {
+ /* just to be safe: */
+ k->pkt->pkt.user_id->flags.primary = 0;
+ }
}
}
}
}
}
+
/* Convert a buffer to a signature. Useful for 0x19 embedded sigs.
- Caller must free the signature when they are done. */
+ * Caller must free the signature when they are done. */
static PKT_signature *
buf_to_sig (const byte * buf, size_t len)
{
@@ -3051,25 +3070,26 @@ buf_to_sig (const byte * buf, size_t len)
return sig;
}
-/* Use the self-signed data to fill in various fields in subkeys.
-
- KEYBLOCK is the whole keyblock. SUBNODE is the subkey to fill in.
-
- Sets the following fields on the subkey:
- main_keyid
- flags.valid if the subkey has a valid self-sig binding
- flags.revoked
- flags.backsig
- pubkey_usage
- has_expired
- expired_date
-
- On this subkey's most revent valid self-signed packet, the
- following field is set:
-
- flags.chosen_selfsig
- */
+/* Use the self-signed data to fill in various fields in subkeys.
+ *
+ * KEYBLOCK is the whole keyblock. SUBNODE is the subkey to fill in.
+ *
+ * Sets the following fields on the subkey:
+ *
+ * main_keyid
+ * flags.valid if the subkey has a valid self-sig binding
+ * flags.revoked
+ * flags.backsig
+ * pubkey_usage
+ * has_expired
+ * expired_date
+ *
+ * On this subkey's most revent valid self-signed packet, the
+ * following field is set:
+ *
+ * flags.chosen_selfsig
+ */
static void
merge_selfsigs_subkey (ctrl_t ctrl, kbnode_t keyblock, kbnode_t subnode)
{
@@ -3115,13 +3135,13 @@ merge_selfsigs_subkey (ctrl_t ctrl, kbnode_t keyblock, kbnode_t subnode)
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. */
+ * 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
@@ -3171,6 +3191,7 @@ merge_selfsigs_subkey (ctrl_t ctrl, kbnode_t keyblock, kbnode_t subnode)
key_expire = keytimestamp + buf32_to_u32 (p);
else
key_expire = 0;
+
subpk->has_expired = key_expire >= curtime ? 0 : key_expire;
subpk->expiredate = key_expire;
@@ -3190,7 +3211,7 @@ merge_selfsigs_subkey (ctrl_t ctrl, kbnode_t keyblock, kbnode_t subnode)
sigdate = 0;
/* We do this while() since there may be other embedded
- signatures in the future. We only want 0x19 here. */
+ * signatures in the future. We only want 0x19 here. */
while ((p = enum_sig_subpkt (sig->hashed,
SIGSUBPKT_SIGNATURE, &n, &seq, NULL)))
@@ -3216,7 +3237,7 @@ merge_selfsigs_subkey (ctrl_t ctrl, kbnode_t keyblock, kbnode_t subnode)
seq = 0;
/* It is safe to have this in the unhashed area since the 0x19
- is located on the selfsig for convenience, not security. */
+ * is located on the selfsig for convenience, not security. */
while ((p = enum_sig_subpkt (sig->unhashed, SIGSUBPKT_SIGNATURE,
&n, &seq, NULL)))
@@ -3242,7 +3263,7 @@ merge_selfsigs_subkey (ctrl_t ctrl, kbnode_t keyblock, kbnode_t subnode)
if (backsig)
{
/* At this point, backsig contains the most recent 0x19 sig.
- Let's see if it is good. */
+ * Let's see if it is good. */
/* 2==valid, 1==invalid, 0==didn't check */
if (check_backsig (mainpk, subpk, backsig) == 0)
@@ -3257,10 +3278,10 @@ merge_selfsigs_subkey (ctrl_t ctrl, kbnode_t keyblock, kbnode_t subnode)
/* Merge information from the self-signatures with the public key,
- subkeys and user ids to make using them more easy.
-
- See documentation for merge_selfsigs_main, merge_selfsigs_subkey
- and fixup_uidnode for exactly which fields are updated. */
+ * subkeys and user ids to make using them more easy.
+ *
+ * See documentation for merge_selfsigs_main, merge_selfsigs_subkey
+ * and fixup_uidnode for exactly which fields are updated. */
static void
merge_selfsigs (ctrl_t ctrl, kbnode_t keyblock)
{
@@ -3278,8 +3299,8 @@ merge_selfsigs (ctrl_t ctrl, kbnode_t keyblock)
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 */
+ * other places too. FIXME: Figure this out earlier and
+ * don't get to here at all */
g10_exit (1);
}
BUG ();
@@ -3674,22 +3695,22 @@ print_status_key_considered (kbnode_t keyblock, unsigned int flags)
/* A high-level function to lookup keys.
-
- This function builds on top of the low-level keydb API. It first
- searches the database using the description stored in CTX->ITEMS,
- then it filters the results using CTX and, finally, if WANT_SECRET
- is set, it ignores any keys for which no secret key is available.
-
- Unlike the low-level search functions, this function also merges
- all of the self-signed data into the keys, subkeys and user id
- packets (see the merge_selfsigs for details).
-
- On success the key's keyblock is stored at *RET_KEYBLOCK, and the
- specific subkey is stored at *RET_FOUND_KEY. Note that we do not
- return a reference in *RET_FOUND_KEY, i.e. the result must not be
- freed using 'release_kbnode', and it is only valid until
- *RET_KEYBLOCK is deallocated. Therefore, if RET_FOUND_KEY is not
- NULL, then RET_KEYBLOCK must not be NULL. */
+ *
+ * This function builds on top of the low-level keydb API. It first
+ * searches the database using the description stored in CTX->ITEMS,
+ * then it filters the results using CTX and, finally, if WANT_SECRET
+ * is set, it ignores any keys for which no secret key is available.
+ *
+ * Unlike the low-level search functions, this function also merges
+ * all of the self-signed data into the keys, subkeys and user id
+ * packets (see the merge_selfsigs for details).
+ *
+ * On success the key's keyblock is stored at *RET_KEYBLOCK, and the
+ * specific subkey is stored at *RET_FOUND_KEY. Note that we do not
+ * return a reference in *RET_FOUND_KEY, i.e. the result must not be
+ * freed using 'release_kbnode', and it is only valid until
+ * *RET_KEYBLOCK is deallocated. Therefore, if RET_FOUND_KEY is not
+ * NULL, then RET_KEYBLOCK must not be NULL. */
static int
lookup (ctrl_t ctrl, getkey_ctx_t ctx, int want_secret,
kbnode_t *ret_keyblock, kbnode_t *ret_found_key)
@@ -3711,9 +3732,8 @@ lookup (ctrl_t ctrl, getkey_ctx_t ctx, int want_secret,
break;
/* If we are iterating over the entire database, then we need to
- change from KEYDB_SEARCH_MODE_FIRST, which does an implicit
- reset, to KEYDB_SEARCH_MODE_NEXT, which gets the next
- record. */
+ * change from KEYDB_SEARCH_MODE_FIRST, which does an implicit
+ * reset, to KEYDB_SEARCH_MODE_NEXT, which gets the next record. */
if (ctx->nitems && ctx->items->mode == KEYDB_SEARCH_MODE_FIRST)
ctx->items->mode = KEYDB_SEARCH_MODE_NEXT;
@@ -3724,8 +3744,14 @@ lookup (ctrl_t ctrl, getkey_ctx_t ctx, int want_secret,
goto skip;
}
- if (want_secret && agent_probe_any_secret_key (NULL, keyblock))
- goto skip; /* No secret key available. */
+ if (want_secret)
+ {
+ rc = agent_probe_any_secret_key (NULL, keyblock);
+ if (gpg_err_code(rc) == GPG_ERR_NO_SECKEY)
+ goto skip; /* No secret key available. */
+ if (rc)
+ goto found; /* Unexpected error. */
+ }
/* Warning: node flag bits 0 and 1 should be preserved by
* merge_selfsigs. */
@@ -3748,10 +3774,10 @@ lookup (ctrl_t ctrl, getkey_ctx_t ctx, int want_secret,
release_kbnode (keyblock);
keyblock = NULL;
/* The keyblock cache ignores the current "file position".
- Thus, if we request the next result and the cache matches
- (and it will since it is what we just looked for), we'll get
- the same entry back! We can avoid this infinite loop by
- disabling the cache. */
+ * Thus, if we request the next result and the cache matches
+ * (and it will since it is what we just looked for), we'll get
+ * the same entry back! We can avoid this infinite loop by
+ * disabling the cache. */
keydb_disable_caching (ctx->kr_handle);
}
@@ -3960,6 +3986,58 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk)
}
}
+gpg_error_t
+get_seckey_default_or_card (ctrl_t ctrl, PKT_public_key *pk,
+ const byte *fpr_card, size_t fpr_len)
+{
+ gpg_error_t err;
+ strlist_t namelist = NULL;
+
+ const char *def_secret_key = parse_def_secret_key (ctrl);
+
+ if (def_secret_key)
+ add_to_strlist (&namelist, def_secret_key);
+ else if (fpr_card)
+ return get_pubkey_byfprint (ctrl, pk, NULL, fpr_card, fpr_len);
+
+ if (!fpr_card
+ || (def_secret_key && def_secret_key[strlen (def_secret_key)-1] == '!'))
+ err = key_byname (ctrl, NULL, namelist, pk, 1, 0, NULL, NULL);
+ else
+ { /* Default key is specified and card key is also available. */
+ kbnode_t k, keyblock = NULL;
+
+ err = key_byname (ctrl, NULL, namelist, pk, 1, 0, &keyblock, NULL);
+ if (!err)
+ for (k = keyblock; k; k = k->next)
+ {
+ PKT_public_key *pk_candidate;
+ char fpr[MAX_FINGERPRINT_LEN];
+
+ if (k->pkt->pkttype != PKT_PUBLIC_KEY
+ &&k->pkt->pkttype != PKT_PUBLIC_SUBKEY)
+ continue;
+
+ pk_candidate = k->pkt->pkt.public_key;
+ if (!pk_candidate->flags.valid)
+ continue;
+ if (!((pk_candidate->pubkey_usage & USAGE_MASK) & pk->req_usage))
+ continue;
+ fingerprint_from_pk (pk_candidate, fpr, NULL);
+ if (!memcmp (fpr_card, fpr, fpr_len))
+ {
+ release_public_key_parts (pk);
+ copy_public_key (pk, pk_candidate);
+ break;
+ }
+ }
+ release_kbnode (keyblock);
+ }
+
+ free_strlist (namelist);
+
+ return err;
+}
/*********************************************
*********** User ID printing helpers *******
@@ -4225,6 +4303,76 @@ parse_auto_key_locate (char *options)
}
+
+/* The list of key origins. */
+static struct {
+ const char *name;
+ int origin;
+} key_origin_list[] =
+ {
+ { "self", KEYORG_SELF },
+ { "file", KEYORG_FILE },
+ { "url", KEYORG_URL },
+ { "wkd", KEYORG_WKD },
+ { "dane", KEYORG_DANE },
+ { "ks-pref", KEYORG_KS_PREF },
+ { "ks", KEYORG_KS },
+ { "unknown", KEYORG_UNKNOWN }
+ };
+
+/* Parse the argument for --key-origin. Return false on error. */
+int
+parse_key_origin (char *string)
+{
+ int i;
+ char *comma;
+
+ comma = strchr (string, ',');
+ if (comma)
+ *comma = 0;
+
+ if (!ascii_strcasecmp (string, "help"))
+ {
+ log_info (_("valid values for option '%s':\n"), "--key-origin");
+ for (i=0; i < DIM (key_origin_list); i++)
+ log_info (" %s\n", key_origin_list[i].name);
+ g10_exit (1);
+ }
+
+ for (i=0; i < DIM (key_origin_list); i++)
+ if (!ascii_strcasecmp (string, key_origin_list[i].name))
+ {
+ opt.key_origin = key_origin_list[i].origin;
+ xfree (opt.key_origin_url);
+ opt.key_origin_url = NULL;
+ if (comma && comma[1])
+ {
+ opt.key_origin_url = xstrdup (comma+1);
+ trim_spaces (opt.key_origin_url);
+ }
+
+ return 1;
+ }
+
+ if (comma)
+ *comma = ',';
+ return 0;
+}
+
+/* Return a string or "?" for the key ORIGIN. */
+const char *
+key_origin_string (int origin)
+{
+ int i;
+
+ for (i=0; i < DIM (key_origin_list); i++)
+ if (key_origin_list[i].origin == origin)
+ return key_origin_list[i].name;
+ return "?";
+}
+
+
+
/* Returns true if a secret key is available for the public key with
key id KEYID; returns false if not. This function ignores legacy
keys. Note: this is just a fast check and does not tell us whether
diff --git a/g10/gpg.c b/g10/gpg.c
index 80e5197..d2227b3 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -62,6 +62,7 @@
#include "../common/init.h"
#include "../common/mbox-util.h"
#include "../common/shareddefs.h"
+#include "../common/compliance.h"
#if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
#define MY_O_BINARY O_BINARY
@@ -200,6 +201,7 @@ enum cmd_and_opt_values
oWithWKDHash,
oWithColons,
oWithKeyData,
+ oWithKeyOrigin,
oWithTofuInfo,
oWithSigList,
oWithSigCheck,
@@ -418,6 +420,7 @@ enum cmd_and_opt_values
oOnlySignTextIDs,
oDisableSignerUID,
oSender,
+ oKeyOrigin,
oNoop
};
@@ -614,6 +617,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_s (oKeyServer, "keyserver", "@"),
ARGPARSE_s_s (oKeyServerOptions, "keyserver-options", "@"),
+ ARGPARSE_s_s (oKeyOrigin, "key-origin", "@"),
ARGPARSE_s_s (oImportOptions, "import-options", "@"),
ARGPARSE_s_s (oImportFilter, "import-filter", "@"),
ARGPARSE_s_s (oExportOptions, "export-options", "@"),
@@ -782,6 +786,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oWithKeygrip, "with-keygrip", "@"),
ARGPARSE_s_n (oWithSecret, "with-secret", "@"),
ARGPARSE_s_n (oWithWKDHash, "with-wkd-hash", "@"),
+ ARGPARSE_s_n (oWithKeyOrigin, "with-key-origin", "@"),
ARGPARSE_s_s (oDisableCipherAlgo, "disable-cipher-algo", "@"),
ARGPARSE_s_s (oDisablePubkeyAlgo, "disable-pubkey-algo", "@"),
ARGPARSE_s_n (oAllowNonSelfsignedUID, "allow-non-selfsigned-uid", "@"),
@@ -2073,11 +2078,8 @@ parse_tofu_policy (const char *policystr)
}
-/* Parse the value of --compliance. */
-static int
-parse_compliance_option (const char *string)
-{
- struct { const char *keyword; enum cmd_and_opt_values option; } list[] = {
+static struct gnupg_compliance_option compliance_options[] =
+ {
{ "gnupg", oGnuPG },
{ "openpgp", oOpenPGP },
{ "rfc4880bis", oRFC4880bis },
@@ -2088,26 +2090,6 @@ parse_compliance_option (const char *string)
{ "pgp8", oPGP8 },
{ "de-vs", oDE_VS }
};
- int i;
-
- if (!ascii_strcasecmp (string, "help"))
- {
- log_info (_("valid values for option '%s':\n"), "--compliance");
- for (i=0; i < DIM (list); i++)
- log_info (" %s\n", list[i].keyword);
- g10_exit (1);
- }
-
- for (i=0; i < DIM (list); i++)
- if (!ascii_strcasecmp (string, list[i].keyword))
- return list[i].option;
-
- log_error (_("invalid value for option '%s'\n"), "--compliance");
- if (!opt.quiet)
- log_info (_("(use \"help\" to list choices)\n"));
- g10_exit (1);
-}
-
/* Helper to set compliance related options. This is a separate
@@ -2166,6 +2148,7 @@ set_compliance_option (enum cmd_and_opt_values option)
case oDE_VS:
set_compliance_option (oOpenPGP);
opt.compliance = CO_DE_VS;
+ opt.force_mdc = 1;
/* Fixme: Change other options. */
break;
@@ -2349,6 +2332,9 @@ main (int argc, char **argv)
dotlock_create (NULL, 0); /* Register lock file cleanup. */
+ /* Tell the compliance module who we are. */
+ gnupg_initialize_compliance (GNUPG_MODULE_NAME_GPG);
+
opt.autostart = 1;
opt.session_env = session_env_new ();
if (!opt.session_env)
@@ -2371,9 +2357,10 @@ main (int argc, char **argv)
opt.max_cert_depth = 5;
opt.escape_from = 1;
opt.flags.require_cross_cert = 1;
- opt.import_options = 0;
+ opt.import_options = IMPORT_REPAIR_KEYS;
opt.export_options = EXPORT_ATTRIBUTES;
- opt.keyserver_options.import_options = IMPORT_REPAIR_PKS_SUBKEY_BUG;
+ opt.keyserver_options.import_options = (IMPORT_REPAIR_KEYS
+ | IMPORT_REPAIR_PKS_SUBKEY_BUG);
opt.keyserver_options.export_options = EXPORT_ATTRIBUTES;
opt.keyserver_options.options = KEYSERVER_HONOR_PKA_RECORD;
opt.verify_options = (LIST_SHOW_UID_VALIDITY
@@ -2748,6 +2735,10 @@ main (int argc, char **argv)
opt.with_wkd_hash = 1;
break;
+ case oWithKeyOrigin:
+ opt.with_key_origin = 1;
+ break;
+
case oSecretKeyring:
/* Ignore this old option. */
break;
@@ -2861,7 +2852,15 @@ main (int argc, char **argv)
break;
case oCompliance:
- set_compliance_option (parse_compliance_option (pargs.r.ret_str));
+ {
+ int compliance = gnupg_parse_compliance_option
+ (pargs.r.ret_str,
+ compliance_options, DIM (compliance_options),
+ opt.quiet);
+ if (compliance < 0)
+ g10_exit (1);
+ set_compliance_option (compliance);
+ }
break;
case oOpenPGP:
case oRFC2440:
@@ -3471,6 +3470,12 @@ main (int argc, char **argv)
release_akl();
break;
+ case oKeyOrigin:
+ if(!parse_key_origin (pargs.r.ret_str))
+ log_error (_("invalid argument for option \"%.50s\"\n"),
+ "--key-origin");
+ break;
+
case oEnableLargeRSA:
#if SECMEM_BUFFER_SIZE >= 65536
opt.flags.large_rsa=1;
@@ -3855,19 +3860,22 @@ main (int argc, char **argv)
switch(badtype)
{
case PREFTYPE_SYM:
- log_info(_("you may not use cipher algorithm '%s'"
- " while in %s mode\n"),
- badalg,compliance_option_string());
+ log_info (_("cipher algorithm '%s'"
+ " may not be used in %s mode\n"),
+ badalg,
+ gnupg_compliance_option_string (opt.compliance));
break;
case PREFTYPE_HASH:
- log_info(_("you may not use digest algorithm '%s'"
- " while in %s mode\n"),
- badalg,compliance_option_string());
+ log_info (_("digest algorithm '%s'"
+ " may not be used in %s mode\n"),
+ badalg,
+ gnupg_compliance_option_string (opt.compliance));
break;
case PREFTYPE_ZIP:
- log_info(_("you may not use compression algorithm '%s'"
- " while in %s mode\n"),
- badalg,compliance_option_string());
+ log_info (_("compression algorithm '%s'"
+ " may not be used in %s mode\n"),
+ badalg,
+ gnupg_compliance_option_string (opt.compliance));
break;
default:
BUG();
@@ -3877,6 +3885,41 @@ main (int argc, char **argv)
}
}
+ /* Check our chosen algorithms against the list of allowed
+ * algorithms in the current compliance mode, and fail hard if it
+ * is not. This is us being nice to the user informing her early
+ * that the chosen algorithms are not available. We also check
+ * and enforce this right before the actual operation. */
+ if (opt.def_cipher_algo
+ && ! gnupg_cipher_is_allowed (opt.compliance,
+ cmd == aEncr
+ || cmd == aSignEncr
+ || cmd == aEncrSym
+ || cmd == aSym
+ || cmd == aSignSym
+ || cmd == aSignEncrSym,
+ opt.def_cipher_algo,
+ GCRY_CIPHER_MODE_NONE))
+ log_error (_("cipher algorithm '%s' may not be used in %s mode\n"),
+ openpgp_cipher_algo_name (opt.def_cipher_algo),
+ gnupg_compliance_option_string (opt.compliance));
+
+ if (opt.def_digest_algo
+ && ! gnupg_digest_is_allowed (opt.compliance,
+ cmd == aSign
+ || cmd == aSignEncr
+ || cmd == aSignEncrSym
+ || cmd == aSignSym
+ || cmd == aClearsign,
+ opt.def_digest_algo))
+ log_error (_("digest algorithm '%s' may not be used in %s mode\n"),
+ gcry_md_algo_name (opt.def_digest_algo),
+ gnupg_compliance_option_string (opt.compliance));
+
+ /* Fail hard. */
+ if (log_get_errorcount (0))
+ g10_exit (2);
+
/* Set the random seed file. */
if( use_random_seed ) {
char *p = make_filename (gnupg_homedir (), "random_seed", NULL );
@@ -4086,7 +4129,8 @@ main (int argc, char **argv)
" with --s2k-mode 0\n"));
else if(PGP6 || PGP7)
log_error(_("you cannot use --symmetric --encrypt"
- " while in %s mode\n"),compliance_option_string());
+ " in %s mode\n"),
+ gnupg_compliance_option_string (opt.compliance));
else
{
if( (rc = encrypt_crypt (ctrl, -1, fname, remusr, 1, NULL, -1)) )
@@ -4146,7 +4190,8 @@ main (int argc, char **argv)
" with --s2k-mode 0\n"));
else if(PGP6 || PGP7)
log_error(_("you cannot use --symmetric --sign --encrypt"
- " while in %s mode\n"),compliance_option_string());
+ " in %s mode\n"),
+ gnupg_compliance_option_string (opt.compliance));
else
{
if( argc )
@@ -4447,11 +4492,11 @@ main (int argc, char **argv)
{
const char *x_fpr, *x_expire;
- if (argc != 2)
- wrong_args ("--quick-set-exipre FINGERPRINT EXPIRE");
+ if (argc < 2)
+ wrong_args ("--quick-set-exipre FINGERPRINT EXPIRE [SUBKEY-FPRS]");
x_fpr = *argv++; argc--;
x_expire = *argv++; argc--;
- keyedit_quick_set_expire (ctrl, x_fpr, x_expire);
+ keyedit_quick_set_expire (ctrl, x_fpr, x_expire, argv);
}
break;
@@ -4470,7 +4515,8 @@ main (int argc, char **argv)
case aFastImport:
opt.import_options |= IMPORT_FAST; /* fall through */
case aImport:
- import_keys (ctrl, argc? argv:NULL, argc, NULL, opt.import_options);
+ import_keys (ctrl, argc? argv:NULL, argc, NULL,
+ opt.import_options, opt.key_origin, opt.key_origin_url);
break;
/* TODO: There are a number of command that use this same
@@ -4558,7 +4604,7 @@ main (int argc, char **argv)
sl = NULL;
for( ; argc; argc--, argv++ )
append_to_strlist2( &sl, *argv, utf8_strings );
- rc = keyserver_fetch (ctrl, sl);
+ rc = keyserver_fetch (ctrl, sl, opt.key_origin);
if(rc)
{
write_status_failure ("fetch-keys", rc);
diff --git a/g10/gpgcompose.c b/g10/gpgcompose.c
index 4a2cb81..2b42bfb 100644
--- a/g10/gpgcompose.c
+++ b/g10/gpgcompose.c
@@ -81,7 +81,7 @@ filter_pop (iobuf_t out, int expected_type)
"but current container is a %s container.\n",
pkttype_str (f->pkttype), pkttype_str (expected_type));
- if (f->pkttype == PKT_ENCRYPTED || f->pkttype == PKT_ENCRYPTED_MDC)
+ if (f->pkttype == PKT_ENCRYPTED)
{
err = iobuf_pop_filter (out, f->func, f->context);
if (err)
@@ -281,18 +281,18 @@ show_help (struct option options[])
{
const char *o = option[0] ? option : "ARG";
l = strlen (o);
- fprintf (stderr, "%s", o);
+ fprintf (stdout, "%s", o);
}
if (! help)
{
- fputc ('\n', stderr);
+ fputc ('\n', stdout);
continue;
}
if (option)
for (j = l; j < max_length + 2; j ++)
- fputc (' ', stderr);
+ fputc (' ', stdout);
#define BOLD_START "\033[1m"
#define NORMAL_RESTORE "\033[0m"
@@ -306,7 +306,7 @@ show_help (struct option options[])
if (! option)
space = 72;
formatted = format_text (tmp, space, space + 4);
- if (!format_text)
+ if (!formatted)
abort ();
if (tmp != help)
@@ -314,7 +314,7 @@ show_help (struct option options[])
if (! option)
{
- fprintf (stderr, "\n%s\n", formatted);
+ printf ("\n%s\n", formatted);
break;
}
@@ -330,10 +330,10 @@ show_help (struct option options[])
if (p != formatted)
for (j = 0; j < max_length + 2; j ++)
- fputc (' ', stderr);
+ fputc (' ', stdout);
- fwrite (p, l, 1, stderr);
- fputc ('\n', stderr);
+ fwrite (p, l, 1, stdout);
+ fputc ('\n', stdout);
}
xfree (formatted);
@@ -512,7 +512,8 @@ static struct option major_options[] = {
{ "--encrypted-mdc", encrypted,
"Create a symmetrically encrypted and integrity protected data packet." },
{ "--encrypted-pop", encrypted_pop,
- "Pop an encryption container." },
+ "Pop the most recent encryption container started by either"
+ " --encrypted or --encrypted-mdc." },
{ "--compressed", NULL, "Create a compressed data packet." },
{ "--literal", literal, "Create a literal (plaintext) data packet." },
{ "--signature", signature, "Create a signature packet." },
@@ -2534,7 +2535,9 @@ encrypted (const char *option, int argc, char *argv[], void *cookie)
argc, argv);
if (! session_key.algo)
- log_fatal ("%s: no session key configured.\n", option);
+ log_fatal ("%s: no session key configured\n"
+ " (use e.g. --sk-esk PASSWORD or --pk-esk KEYID).\n",
+ option);
memset (&e, 0, sizeof (e));
/* We only need to set E->LEN, E->EXTRALEN (if E->LEN is not
@@ -2580,24 +2583,36 @@ encrypted (const char *option, int argc, char *argv[], void *cookie)
return processed;
}
+static struct option encrypted_pop_options[] = {
+ { NULL, NULL,
+ "Example:\n\n"
+ " $ gpgcompose --sk-esk PASSWORD \\\n"
+ " --encrypted-mdc \\\n"
+ " --literal --value foo \\\n"
+ " --encrypted-pop | " GPG_NAME " --list-packets" }
+};
+
static int
encrypted_pop (const char *option, int argc, char *argv[], void *cookie)
{
iobuf_t out = cookie;
+ int processed;
- (void) argc;
- (void) argv;
+ processed = process_options (option,
+ major_options,
+ encrypted_pop_options,
+ NULL,
+ global_options, NULL,
+ argc, argv);
+ /* We only support a single option, --help, which causes the program
+ * to exit. */
+ log_assert (processed == 0);
- if (strcmp (option, "--encrypted-pop") == 0)
- filter_pop (out, PKT_ENCRYPTED);
- else if (strcmp (option, "--encrypted-mdc-pop") == 0)
- filter_pop (out, PKT_ENCRYPTED_MDC);
- else
- log_fatal ("%s: option not handled by this function!\n", option);
+ filter_pop (out, PKT_ENCRYPTED);
debug ("Popped encryption container.\n");
- return 0;
+ return processed;
}
struct data
@@ -3048,3 +3063,23 @@ show_basic_key_info (ctrl_t ctrl, KBNODE keyblock)
(void)ctrl;
(void) keyblock;
}
+
+int
+keyedit_print_one_sig (ctrl_t ctrl, estream_t fp,
+ int rc, kbnode_t keyblock, kbnode_t node,
+ int *inv_sigs, int *no_key, int *oth_err,
+ int is_selfsig, int print_without_key, int extended)
+{
+ (void) ctrl;
+ (void) fp;
+ (void) rc;
+ (void) keyblock;
+ (void) node;
+ (void) inv_sigs;
+ (void) no_key;
+ (void) oth_err;
+ (void) is_selfsig;
+ (void) print_without_key;
+ (void) extended;
+ return 0;
+}
diff --git a/g10/gpgv.c b/g10/gpgv.c
index ddbcd7d..fb274b3 100644
--- a/g10/gpgv.c
+++ b/g10/gpgv.c
@@ -270,6 +270,7 @@ main( int argc, char **argv )
if ((rc = verify_signatures (ctrl, argc, argv)))
log_error("verify signatures failed: %s\n", gpg_strerror (rc) );
+ keydb_release (ctrl->cached_getkey_kdb);
xfree (ctrl);
/* cleanup */
diff --git a/g10/import.c b/g10/import.c
index d9d658b..8136625 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -1,6 +1,6 @@
/* import.c - import a key into our key storage.
* Copyright (C) 1998-2007, 2010-2011 Free Software Foundation, Inc.
- * Copyright (C) 2014, 2016 Werner Koch
+ * Copyright (C) 2014, 2016, 2017 Werner Koch
*
* This file is part of GnuPG.
*
@@ -40,6 +40,7 @@
#include "../common/membuf.h"
#include "../common/init.h"
#include "../common/mbox-util.h"
+#include "key-check.h"
struct import_stats_s
@@ -96,7 +97,8 @@ struct import_filter_s import_filter;
static int import (ctrl_t ctrl,
IOBUF inp, const char* fname, struct import_stats_s *stats,
unsigned char **fpr, size_t *fpr_len, unsigned int options,
- import_screener_t screener, void *screener_arg);
+ import_screener_t screener, void *screener_arg,
+ int origin, const char *url);
static int read_block (IOBUF a, int with_meta,
PACKET **pending_pkt, kbnode_t *ret_root, int *r_v3keys);
static void revocation_present (ctrl_t ctrl, kbnode_t keyblock);
@@ -105,7 +107,8 @@ static int import_one (ctrl_t ctrl,
struct import_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);
+ import_screener_t screener, void *screener_arg,
+ int origin, const char *url);
static int import_secret_one (ctrl_t ctrl, kbnode_t keyblock,
struct import_stats_s *stats, int batch,
unsigned int options, int for_migration,
@@ -117,10 +120,15 @@ static int chk_self_sigs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid,
static int delete_inv_parts (ctrl_t ctrl, kbnode_t keyblock,
u32 *keyid, unsigned int options);
static int any_uid_left (kbnode_t keyblock);
-static int merge_blocks (ctrl_t ctrl, kbnode_t keyblock_orig,
+static int merge_blocks (ctrl_t ctrl, unsigned int options,
+ kbnode_t keyblock_orig,
kbnode_t keyblock, u32 *keyid,
+ u32 curtime, int origin, const char *url,
int *n_uids, int *n_sigs, int *n_subk );
-static int append_uid (kbnode_t keyblock, kbnode_t node, int *n_sigs);
+static gpg_error_t append_new_uid (unsigned int options,
+ kbnode_t keyblock, kbnode_t node,
+ u32 curtime, int origin, const char *url,
+ int *n_sigs);
static int append_key (kbnode_t keyblock, kbnode_t node, int *n_sigs);
static int merge_sigs (kbnode_t dst, kbnode_t src, int *n_sigs);
static int merge_keysigs (kbnode_t dst, kbnode_t src, int *n_sigs);
@@ -179,6 +187,9 @@ parse_import_options(char *str,unsigned int *options,int noisy)
N_("assume the GnuPG key backup format")},
{"import-restore", IMPORT_RESTORE, NULL, NULL},
+ {"repair-keys", IMPORT_REPAIR_KEYS, NULL,
+ N_("repair keys on import")},
+
/* Aliases for backward compatibility */
{"allow-local-sigs",IMPORT_LOCAL_SIGS,NULL,NULL},
{"repair-hkp-subkey-bug",IMPORT_REPAIR_PKS_SUBKEY_BUG,NULL,NULL},
@@ -426,7 +437,8 @@ import_keys_internal (ctrl_t ctrl, iobuf_t inp, char **fnames, int nnames,
import_stats_t stats_handle,
unsigned char **fpr, size_t *fpr_len,
unsigned int options,
- import_screener_t screener, void *screener_arg)
+ import_screener_t screener, void *screener_arg,
+ int origin, const char *url)
{
int i;
int rc = 0;
@@ -438,7 +450,7 @@ import_keys_internal (ctrl_t ctrl, iobuf_t inp, char **fnames, int nnames,
if (inp)
{
rc = import (ctrl, inp, "[stream]", stats, fpr, fpr_len, options,
- screener, screener_arg);
+ screener, screener_arg, origin, url);
}
else
{
@@ -463,7 +475,7 @@ import_keys_internal (ctrl_t ctrl, iobuf_t inp, char **fnames, int nnames,
else
{
rc = import (ctrl, inp2, fname, stats, fpr, fpr_len, options,
- screener, screener_arg);
+ screener, screener_arg, origin, url);
iobuf_close (inp2);
/* Must invalidate that ugly cache to actually close it. */
iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)fname);
@@ -497,28 +509,21 @@ import_keys_internal (ctrl_t ctrl, iobuf_t inp, char **fnames, int nnames,
void
import_keys (ctrl_t ctrl, char **fnames, int nnames,
- import_stats_t stats_handle, unsigned int options )
+ import_stats_t stats_handle, unsigned int options,
+ int origin, const char *url)
{
import_keys_internal (ctrl, NULL, fnames, nnames, stats_handle,
- NULL, NULL, options, NULL, NULL);
+ NULL, NULL, options, NULL, NULL, origin, url);
}
-int
-import_keys_stream (ctrl_t ctrl, IOBUF inp, import_stats_t 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);
-}
-
-/* Variant of import_keys_stream reading from an estream_t. */
int
import_keys_es_stream (ctrl_t ctrl, estream_t fp,
import_stats_t stats_handle,
unsigned char **fpr, size_t *fpr_len,
unsigned int options,
- import_screener_t screener, void *screener_arg)
+ import_screener_t screener, void *screener_arg,
+ int origin, const char *url)
{
int rc;
iobuf_t inp;
@@ -533,7 +538,7 @@ import_keys_es_stream (ctrl_t ctrl, estream_t fp,
rc = import_keys_internal (ctrl, inp, NULL, 0, stats_handle,
fpr, fpr_len, options,
- screener, screener_arg);
+ screener, screener_arg, origin, url);
iobuf_close (inp);
return rc;
@@ -543,7 +548,8 @@ import_keys_es_stream (ctrl_t ctrl, estream_t fp,
static int
import (ctrl_t ctrl, IOBUF inp, const char* fname,struct import_stats_s *stats,
unsigned char **fpr,size_t *fpr_len, unsigned int options,
- import_screener_t screener, void *screener_arg)
+ import_screener_t screener, void *screener_arg,
+ int origin, const char *url)
{
PACKET *pending_pkt = NULL;
kbnode_t keyblock = NULL; /* Need to initialize because gcc can't
@@ -571,13 +577,13 @@ import (ctrl_t ctrl, IOBUF inp, const char* fname,struct import_stats_s *stats,
if (keyblock->pkt->pkttype == PKT_PUBLIC_KEY)
rc = import_one (ctrl, keyblock,
stats, fpr, fpr_len, options, 0, 0,
- screener, screener_arg);
+ screener, screener_arg, origin, url);
else if (keyblock->pkt->pkttype == PKT_SECRET_KEY)
rc = import_secret_one (ctrl, keyblock, stats,
opt.batch, options, 0,
screener, screener_arg);
else if (keyblock->pkt->pkttype == PKT_SIGNATURE
- && keyblock->pkt->pkt.signature->sig_class == 0x20 )
+ && IS_KEY_REV (keyblock->pkt->pkt.signature) )
rc = import_revoke_cert (ctrl, keyblock, stats);
else
{
@@ -824,7 +830,7 @@ read_block( IOBUF a, int with_meta,
in_v3key = 0;
if (!root && pkt->pkttype == PKT_SIGNATURE
- && pkt->pkt.signature->sig_class == 0x20 )
+ && IS_KEY_REV (pkt->pkt.signature) )
{
/* This is a revocation certificate which is handled in a
* special way. */
@@ -927,7 +933,7 @@ fix_pks_corruption (ctrl_t ctrl, kbnode_t keyblock)
sknode=node;
}
else if (node->pkt->pkttype == PKT_SIGNATURE
- && node->pkt->pkt.signature->sig_class == 0x18
+ && IS_SUBKEY_SIG (node->pkt->pkt.signature)
&& keycount >= 2
&& !node->next)
{
@@ -1380,19 +1386,231 @@ apply_drop_sig_filter (ctrl_t ctrl, kbnode_t keyblock, recsel_expr_t selector)
}
+/* Insert a key origin into a public key packet. */
+static gpg_error_t
+insert_key_origin_pk (PKT_public_key *pk, u32 curtime,
+ int origin, const char *url)
+{
+ if (origin == KEYORG_WKD || origin == KEYORG_DANE)
+ {
+ /* For WKD and DANE we insert origin information also for the
+ * key but we don't record the URL because we have have no use
+ * for that: An update using a keyserver has higher precedence
+ * and will thus update this origin info. For refresh using WKD
+ * or DANE we need to go via the User ID anyway. Recall that we
+ * are only inserting a new key. */
+ pk->keyorg = origin;
+ pk->keyupdate = curtime;
+ }
+ else if (origin == KEYORG_KS && url)
+ {
+ /* If the key was retrieved from a keyserver using a fingerprint
+ * request we add the meta information. Note that the use of a
+ * fingerprint needs to be enforced by the caller of the import
+ * function. This is commonly triggered by verifying a modern
+ * signature which has an Issuer Fingerprint signature
+ * subpacket. */
+ pk->keyorg = origin;
+ pk->keyupdate = curtime;
+ xfree (pk->updateurl);
+ pk->updateurl = xtrystrdup (url);
+ if (!pk->updateurl)
+ return gpg_error_from_syserror ();
+ }
+ else if (origin == KEYORG_FILE)
+ {
+ pk->keyorg = origin;
+ pk->keyupdate = curtime;
+ }
+ else if (origin == KEYORG_URL)
+ {
+ pk->keyorg = origin;
+ pk->keyupdate = curtime;
+ if (url)
+ {
+ xfree (pk->updateurl);
+ pk->updateurl = xtrystrdup (url);
+ if (!pk->updateurl)
+ return gpg_error_from_syserror ();
+ }
+ }
+
+ return 0;
+}
+
+
+/* Insert a key origin into a user id packet. */
+static gpg_error_t
+insert_key_origin_uid (PKT_user_id *uid, u32 curtime,
+ int origin, const char *url)
+
+{
+ if (origin == KEYORG_WKD || origin == KEYORG_DANE)
+ {
+ /* We insert origin information on a UID only when we received
+ * them via the Web Key Directory or a DANE record. The key we
+ * receive here from the WKD has been filtered to contain only
+ * the user ID as looked up in the WKD. For a DANE origin we
+ * this should also be the case. Thus we will see here only one
+ * user id. */
+ uid->keyorg = origin;
+ uid->keyupdate = curtime;
+ if (url)
+ {
+ xfree (uid->updateurl);
+ uid->updateurl = xtrystrdup (url);
+ if (!uid->updateurl)
+ return gpg_error_from_syserror ();
+ }
+ }
+ else if (origin == KEYORG_KS && url)
+ {
+ /* If the key was retrieved from a keyserver using a fingerprint
+ * request we mark that also in the user ID. However we do not
+ * store the keyserver URL in the UID. A later update (merge)
+ * from a more trusted source will replace this info. */
+ uid->keyorg = origin;
+ uid->keyupdate = curtime;
+ }
+ else if (origin == KEYORG_FILE)
+ {
+ uid->keyorg = origin;
+ uid->keyupdate = curtime;
+ }
+ else if (origin == KEYORG_URL)
+ {
+ uid->keyorg = origin;
+ uid->keyupdate = curtime;
+ }
+
+ return 0;
+}
+
+
+/* Apply meta data to KEYBLOCK. This sets the origin of the key to
+ * ORIGIN and the updateurl to URL. Note that this function is only
+ * used for a new key, that is not when we are merging keys. */
+static gpg_error_t
+insert_key_origin (kbnode_t keyblock, int origin, const char *url)
+{
+ gpg_error_t err;
+ kbnode_t node;
+ u32 curtime = make_timestamp ();
+
+ for (node = keyblock; node; node = node->next)
+ {
+ if (is_deleted_kbnode (node))
+ ;
+ else if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+ {
+ err = insert_key_origin_pk (node->pkt->pkt.public_key, curtime,
+ origin, url);
+ if (err)
+ return err;
+ }
+ else if (node->pkt->pkttype == PKT_USER_ID)
+ {
+ err = insert_key_origin_uid (node->pkt->pkt.user_id, curtime,
+ origin, url);
+ if (err)
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+
+/* Update meta data on KEYBLOCK. This updates the key origin on the
+ * public key according to ORIGIN and URL. The UIDs are already
+ * updated when this function is called. */
+static gpg_error_t
+update_key_origin (kbnode_t keyblock, u32 curtime, int origin, const char *url)
+{
+ PKT_public_key *pk;
+
+ log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
+ pk = keyblock->pkt->pkt.public_key;
+
+ if (pk->keyupdate > curtime)
+ ; /* Don't do it for a time warp. */
+ else if (origin == KEYORG_WKD || origin == KEYORG_DANE)
+ {
+ /* We only update the origin info if they either have never been
+ * set or are the origin was the same as the new one. If this
+ * is WKD we also update the UID to show from which user id this
+ * was updated. */
+ if (!pk->keyorg || pk->keyorg == KEYORG_WKD || pk->keyorg == KEYORG_DANE)
+ {
+ pk->keyorg = origin;
+ pk->keyupdate = curtime;
+ xfree (pk->updateurl);
+ pk->updateurl = NULL;
+ if (origin == KEYORG_WKD && url)
+ {
+ pk->updateurl = xtrystrdup (url);
+ if (!pk->updateurl)
+ return gpg_error_from_syserror ();
+ }
+ }
+ }
+ else if (origin == KEYORG_KS)
+ {
+ /* All updates from a keyserver are considered to have the
+ * freshed key. Thus we always set the new key origin. */
+ pk->keyorg = origin;
+ pk->keyupdate = curtime;
+ xfree (pk->updateurl);
+ pk->updateurl = NULL;
+ if (url)
+ {
+ pk->updateurl = xtrystrdup (url);
+ if (!pk->updateurl)
+ return gpg_error_from_syserror ();
+ }
+ }
+ else if (origin == KEYORG_FILE)
+ {
+ /* Updates from a file are considered to be fresh. */
+ pk->keyorg = origin;
+ pk->keyupdate = curtime;
+ xfree (pk->updateurl);
+ pk->updateurl = NULL;
+ }
+ else if (origin == KEYORG_URL)
+ {
+ /* Updates from a URL are considered to be fresh. */
+ pk->keyorg = origin;
+ pk->keyupdate = curtime;
+ xfree (pk->updateurl);
+ pk->updateurl = NULL;
+ if (url)
+ {
+ pk->updateurl = xtrystrdup (url);
+ if (!pk->updateurl)
+ return gpg_error_from_syserror ();
+ }
+ }
+
+ return 0;
+}
+
+
/*
* 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.
+ * even most error messages are suppressed. ORIGIN is the origin of
+ * the key (0 for unknown) and URL the corresponding URL.
*/
static int
import_one (ctrl_t ctrl,
kbnode_t keyblock, struct import_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)
+ import_screener_t screener, void *screener_arg,
+ int origin, const char *url)
{
PKT_public_key *pk;
PKT_public_key *pk_orig = NULL;
@@ -1482,6 +1700,9 @@ import_one (ctrl_t ctrl,
log_info (_("key %s: PKS subkey corruption repaired\n"),
keystr_from_pk(pk));
+ if ((options & IMPORT_REPAIR_KEYS))
+ key_check_all_keysigs (ctrl, 1, keyblock, 0, 0);
+
if (chk_self_sigs (ctrl, keyblock, keyid, &non_self))
return 0; /* Invalid keyblock - error already printed. */
@@ -1592,6 +1813,7 @@ import_one (ctrl_t ctrl,
else if (rc ) /* Insert this key. */
{
KEYDB_HANDLE hd;
+ int n_sigs_cleaned, n_uids_cleaned;
hd = keydb_new ();
if (!hd)
@@ -1607,6 +1829,24 @@ import_one (ctrl_t ctrl,
if (opt.verbose > 1 )
log_info (_("writing to '%s'\n"), keydb_get_resource_name (hd) );
+ if ((options & IMPORT_CLEAN))
+ clean_key (ctrl, keyblock, opt.verbose, (options&IMPORT_MINIMAL),
+ &n_uids_cleaned,&n_sigs_cleaned);
+
+ /* Unless we are in restore mode apply meta data to the
+ * keyblock. Note that this will never change the first packet
+ * and thus the address of KEYBLOCK won't change. */
+ if ( !(options & IMPORT_RESTORE) )
+ {
+ rc = insert_key_origin (keyblock, origin, url);
+ if (rc)
+ {
+ log_error ("insert_key_origin failed: %s\n", gpg_strerror (rc));
+ keydb_release (hd);
+ return GPG_ERR_GENERAL;
+ }
+ }
+
rc = keydb_insert_keyblock (hd, keyblock );
if (rc)
log_error (_("error writing keyring '%s': %s\n"),
@@ -1643,10 +1883,11 @@ import_one (ctrl_t ctrl,
stats->imported++;
new_key = 1;
}
- else /* merge */
+ else /* Merge the key. */
{
KEYDB_HANDLE hd;
int n_uids, n_sigs, n_subk, n_sigs_cleaned, n_uids_cleaned;
+ u32 curtime = make_timestamp ();
/* Compare the original against the new key; just to be sure nothing
* weird is going on */
@@ -1692,8 +1933,9 @@ import_one (ctrl_t ctrl,
clear_kbnode_flags( keyblock_orig );
clear_kbnode_flags( keyblock );
n_uids = n_sigs = n_subk = n_uids_cleaned = 0;
- rc = merge_blocks (ctrl, keyblock_orig, keyblock,
- keyid, &n_uids, &n_sigs, &n_subk );
+ rc = merge_blocks (ctrl, options, keyblock_orig, keyblock, keyid,
+ curtime, origin, url,
+ &n_uids, &n_sigs, &n_subk );
if (rc )
{
keydb_release (hd);
@@ -1706,6 +1948,21 @@ import_one (ctrl_t ctrl,
if (n_uids || n_sigs || n_subk || n_sigs_cleaned || n_uids_cleaned)
{
+ /* Unless we are in restore mode apply meta data to the
+ * keyblock. Note that this will never change the first packet
+ * and thus the address of KEYBLOCK won't change. */
+ if ( !(options & IMPORT_RESTORE) )
+ {
+ rc = update_key_origin (keyblock_orig, curtime, origin, url);
+ if (rc)
+ {
+ log_error ("update_key_origin failed: %s\n",
+ gpg_strerror (rc));
+ keydb_release (hd);
+ goto leave;
+ }
+ }
+
mod_key = 1;
/* KEYBLOCK_ORIG has been updated; write */
rc = keydb_update_keyblock (ctrl, hd, keyblock_orig);
@@ -1763,6 +2020,9 @@ import_one (ctrl_t ctrl,
}
else
{
+ /* Fixme: we do not track the time we last checked a key for
+ * updates. To do this we would need to rewrite even the
+ * keys which have no changes. */
same_key = 1;
if (is_status_enabled ())
print_import_ok (pk, 0);
@@ -2076,7 +2336,8 @@ transfer_secret_keys (ctrl_t ctrl, struct import_stats_s *stats,
{
char *desc = gpg_format_keydesc (ctrl, pk, FORMAT_KEYDESC_IMPORT, 1);
err = agent_import_key (ctrl, desc, &cache_nonce,
- wrappedkey, wrappedkeylen, batch, force);
+ wrappedkey, wrappedkeylen, batch, force,
+ pk->keyid, pk->main_keyid, pk->pubkey_algo);
xfree (desc);
}
if (!err)
@@ -2279,7 +2540,7 @@ import_secret_one (ctrl_t ctrl, kbnode_t keyblock,
the secret keys. FIXME? */
import_one (ctrl, pub_keyblock, stats,
NULL, NULL, options, 1, for_migration,
- screener, screener_arg);
+ screener, screener_arg, 0, NULL);
/* Fixme: We should check for an invalid keyblock and
cancel the secret key import in this case. */
@@ -2365,7 +2626,7 @@ import_revoke_cert (ctrl_t ctrl, kbnode_t node, struct import_stats_s *stats)
log_assert (!node->next );
log_assert (node->pkt->pkttype == PKT_SIGNATURE );
- log_assert (node->pkt->pkt.signature->sig_class == 0x20 );
+ log_assert (IS_KEY_REV (node->pkt->pkt.signature));
keyid[0] = node->pkt->pkt.signature->keyid[0];
keyid[1] = node->pkt->pkt.signature->keyid[1];
@@ -2418,8 +2679,8 @@ import_revoke_cert (ctrl_t ctrl, kbnode_t node, struct import_stats_s *stats)
}
/* it is okay, that node is not in keyblock because
- * check_key_signature works fine for sig_class 0x20 in this
- * special case. */
+ * check_key_signature works fine for sig_class 0x20 (KEY_REV) in
+ * this special case. */
rc = check_key_signature (ctrl, keyblock, node, NULL);
if (rc )
{
@@ -2764,7 +3025,7 @@ delete_inv_parts (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid,
delete_kbnode( node );
}
else if (node->pkt->pkttype == PKT_SIGNATURE
- && node->pkt->pkt.signature->sig_class == 0x20)
+ && IS_KEY_REV (node->pkt->pkt.signature))
{
if (uid_seen )
{
@@ -2796,8 +3057,8 @@ delete_inv_parts (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid,
}
}
else if (node->pkt->pkttype == PKT_SIGNATURE
- && (node->pkt->pkt.signature->sig_class == 0x18
- || node->pkt->pkt.signature->sig_class == 0x28)
+ && (IS_SUBKEY_SIG (node->pkt->pkt.signature)
+ || IS_SUBKEY_REV (node->pkt->pkt.signature))
&& !subkey_seen )
{
if(opt.verbose)
@@ -2973,9 +3234,9 @@ revocation_present (ctrl_t ctrl, kbnode_t keyblock)
if(onode->pkt->pkttype==PKT_USER_ID)
break;
- if(onode->pkt->pkttype==PKT_SIGNATURE &&
- onode->pkt->pkt.signature->sig_class==0x1F &&
- onode->pkt->pkt.signature->revkey)
+ if (onode->pkt->pkttype == PKT_SIGNATURE
+ && IS_KEY_SIG (onode->pkt->pkt.signature)
+ && onode->pkt->pkt.signature->revkey)
{
int idx;
PKT_signature *sig=onode->pkt->pkt.signature;
@@ -2993,14 +3254,14 @@ revocation_present (ctrl_t ctrl, kbnode_t keyblock)
if(inode->pkt->pkttype==PKT_USER_ID)
break;
- if(inode->pkt->pkttype==PKT_SIGNATURE &&
- inode->pkt->pkt.signature->sig_class==0x20 &&
- inode->pkt->pkt.signature->keyid[0]==keyid[0] &&
- inode->pkt->pkt.signature->keyid[1]==keyid[1])
+ if (inode->pkt->pkttype == PKT_SIGNATURE
+ && IS_KEY_REV (inode->pkt->pkt.signature)
+ && inode->pkt->pkt.signature->keyid[0]==keyid[0]
+ && inode->pkt->pkt.signature->keyid[1]==keyid[1])
{
/* Okay, we have a revocation key, and a
- revocation issued by it. Do we have the key
- itself? */
+ * revocation issued by it. Do we have the key
+ * itself? */
int rc;
rc=get_pubkey_byfprint_fast (NULL,sig->revkey[idx].fpr,
@@ -3057,8 +3318,10 @@ revocation_present (ctrl_t ctrl, kbnode_t keyblock)
* Note: We indicate newly inserted packets with NODE_FLAG_A.
*/
static int
-merge_blocks (ctrl_t ctrl, kbnode_t keyblock_orig, kbnode_t keyblock,
- u32 *keyid, int *n_uids, int *n_sigs, int *n_subk )
+merge_blocks (ctrl_t ctrl, unsigned int options,
+ kbnode_t keyblock_orig, kbnode_t keyblock,
+ u32 *keyid, u32 curtime, int origin, const char *url,
+ int *n_uids, int *n_sigs, int *n_subk )
{
kbnode_t onode, node;
int rc, found;
@@ -3069,7 +3332,7 @@ merge_blocks (ctrl_t ctrl, kbnode_t keyblock_orig, kbnode_t keyblock,
if (node->pkt->pkttype == PKT_USER_ID )
break;
else if (node->pkt->pkttype == PKT_SIGNATURE
- && node->pkt->pkt.signature->sig_class == 0x20)
+ && IS_KEY_REV (node->pkt->pkt.signature))
{
/* check whether we already have this */
found = 0;
@@ -3078,7 +3341,7 @@ merge_blocks (ctrl_t ctrl, kbnode_t keyblock_orig, kbnode_t keyblock,
if (onode->pkt->pkttype == PKT_USER_ID )
break;
else if (onode->pkt->pkttype == PKT_SIGNATURE
- && onode->pkt->pkt.signature->sig_class == 0x20
+ && IS_KEY_REV (onode->pkt->pkt.signature)
&& !cmp_signatures(onode->pkt->pkt.signature,
node->pkt->pkt.signature))
{
@@ -3109,7 +3372,7 @@ merge_blocks (ctrl_t ctrl, kbnode_t keyblock_orig, kbnode_t keyblock,
if (node->pkt->pkttype == PKT_USER_ID )
break;
else if (node->pkt->pkttype == PKT_SIGNATURE
- && node->pkt->pkt.signature->sig_class == 0x1F)
+ && IS_KEY_SIG (node->pkt->pkt.signature))
{
/* check whether we already have this */
found = 0;
@@ -3118,7 +3381,7 @@ merge_blocks (ctrl_t ctrl, kbnode_t keyblock_orig, kbnode_t keyblock,
if (onode->pkt->pkttype == PKT_USER_ID)
break;
else if (onode->pkt->pkttype == PKT_SIGNATURE
- && onode->pkt->pkt.signature->sig_class == 0x1F
+ && IS_KEY_SIG (onode->pkt->pkt.signature)
&& !cmp_signatures(onode->pkt->pkt.signature,
node->pkt->pkt.signature))
{
@@ -3172,7 +3435,8 @@ merge_blocks (ctrl_t ctrl, kbnode_t keyblock_orig, kbnode_t keyblock,
break;
if (!onode ) /* this is a new user id: append */
{
- rc = append_uid (keyblock_orig, node, n_sigs);
+ rc = append_new_uid (options, keyblock_orig, node,
+ curtime, origin, url, n_sigs);
if (rc )
return rc;
++*n_uids;
@@ -3248,17 +3512,23 @@ merge_blocks (ctrl_t ctrl, kbnode_t keyblock_orig, kbnode_t keyblock,
/* Helper function for merge_blocks.
- * Append the userid starting with NODE and all signatures to KEYBLOCK.
+ *
+ * Append the new userid starting with NODE and all signatures to
+ * KEYBLOCK. ORIGIN and URL conveys the usual key origin info. The
+ * integer at N_SIGS is updated with the number of new signatures.
*/
-static int
-append_uid (kbnode_t keyblock, kbnode_t node, int *n_sigs)
+static gpg_error_t
+append_new_uid (unsigned int options,
+ kbnode_t keyblock, kbnode_t node, u32 curtime,
+ int origin, const char *url, int *n_sigs)
{
+ gpg_error_t err;
kbnode_t n;
kbnode_t n_where = NULL;
- log_assert (node->pkt->pkttype == PKT_USER_ID );
+ log_assert (node->pkt->pkttype == PKT_USER_ID);
- /* find the position */
+ /* Find the right position for the new user id and its signatures. */
for (n = keyblock; n; n_where = n, n = n->next)
{
if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY
@@ -3272,8 +3542,17 @@ append_uid (kbnode_t keyblock, kbnode_t node, int *n_sigs)
while (node)
{
/* we add a clone to the original keyblock, because this
- * one is released first */
+ * one is released first. */
n = clone_kbnode(node);
+ if (n->pkt->pkttype == PKT_USER_ID
+ && !(options & IMPORT_RESTORE) )
+ {
+ err = insert_key_origin_uid (n->pkt->pkt.user_id,
+ curtime, origin, url);
+ if (err)
+ return err;
+ }
+
if (n_where)
{
insert_kbnode( n_where, n, 0 );
@@ -3312,8 +3591,8 @@ merge_sigs (kbnode_t dst, kbnode_t src, int *n_sigs)
{
if (n->pkt->pkttype != PKT_SIGNATURE )
continue;
- if (n->pkt->pkt.signature->sig_class == 0x18
- || n->pkt->pkt.signature->sig_class == 0x28 )
+ if (IS_SUBKEY_SIG (n->pkt->pkt.signature)
+ || IS_SUBKEY_REV (n->pkt->pkt.signature) )
continue; /* skip signatures which are only valid on subkeys */
found = 0;
diff --git a/g10/key-check.c b/g10/key-check.c
new file mode 100644
index 0000000..d32067b
--- /dev/null
+++ b/g10/key-check.c
@@ -0,0 +1,655 @@
+/* key-check.c - Detect and fix various problems with keys
+ * Copyright (C) 1998-2010 Free Software Foundation, Inc.
+ * Copyright (C) 1998-2017 Werner Koch
+ * Copyright (C) 2015-2017 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 <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "gpg.h"
+#include "options.h"
+#include "packet.h"
+#include "keydb.h"
+#include "main.h"
+#include "../common/ttyio.h"
+#include "../common/i18n.h"
+#include "keyedit.h"
+
+#include "key-check.h"
+
+/* Order two signatures. The actual ordering isn't important. Our
+ * goal is to ensure that identical signatures occur together. */
+static int
+sig_comparison (const void *av, const void *bv)
+{
+ const KBNODE an = *(const KBNODE *) av;
+ const KBNODE bn = *(const KBNODE *) bv;
+ const PKT_signature *a;
+ const PKT_signature *b;
+ int ndataa;
+ int ndatab;
+ int i;
+
+ log_assert (an->pkt->pkttype == PKT_SIGNATURE);
+ log_assert (bn->pkt->pkttype == PKT_SIGNATURE);
+
+ a = an->pkt->pkt.signature;
+ b = bn->pkt->pkt.signature;
+
+ if (a->digest_algo < b->digest_algo)
+ return -1;
+ if (a->digest_algo > b->digest_algo)
+ return 1;
+
+ ndataa = pubkey_get_nsig (a->pubkey_algo);
+ ndatab = pubkey_get_nsig (b->pubkey_algo);
+ if (ndataa != ndatab)
+ return (ndataa < ndatab)? -1 : 1;
+
+ for (i = 0; i < ndataa; i ++)
+ {
+ int c = gcry_mpi_cmp (a->data[i], b->data[i]);
+ if (c != 0)
+ return c;
+ }
+
+ /* Okay, they are equal. */
+ return 0;
+}
+
+
+/* Perform a few sanity checks on a keyblock is okay and possibly
+ * repair some damage. Concretely:
+ *
+ * - Detect duplicate signatures and remove them.
+ *
+ * - Detect out of order signatures and relocate them (e.g., a sig
+ * over user id X located under subkey Y).
+ *
+ * Note: this function does not remove signatures that don't belong or
+ * components that are not signed! (Although it would be trivial to
+ * do so.)
+ *
+ * If ONLY_SELFSIGS is true, then this function only reorders self
+ * signatures (it still checks all signatures for duplicates,
+ * however).
+ *
+ * Allowed values for MODE are:
+ * -1 - print to the TTY
+ * 0 - print to stdout
+ * 1 - use log_info.
+ *
+ * Returns true if the keyblock was modified. */
+int
+key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb,
+ int only_selected, int only_selfsigs)
+{
+ gpg_error_t err;
+ estream_t fp = mode < 0? NULL : mode ? log_get_stream () : es_stdout;
+ PKT_public_key *pk;
+ KBNODE n, n_next, *n_prevp, n2;
+ char *pending_desc = NULL;
+ PKT_public_key *issuer;
+ KBNODE last_printed_component;
+ KBNODE current_component = NULL;
+ int dups = 0;
+ int missing_issuer = 0;
+ int reordered = 0;
+ int bad_signature = 0;
+ int missing_selfsig = 0;
+ int modified = 0;
+
+ log_assert (kb->pkt->pkttype == PKT_PUBLIC_KEY);
+ pk = kb->pkt->pkt.public_key;
+
+ /* First we look for duplicates. */
+ {
+ int nsigs;
+ kbnode_t *sigs;
+ int i;
+ int last_i;
+
+ /* Count the sigs. */
+ for (nsigs = 0, n = kb; n; n = n->next)
+ {
+ if (is_deleted_kbnode (n))
+ continue;
+ else if (n->pkt->pkttype == PKT_SIGNATURE)
+ nsigs ++;
+ }
+
+ if (!nsigs)
+ return 0; /* No signatures at all. */
+
+ /* Add them all to the SIGS array. */
+ sigs = xtrycalloc (nsigs, sizeof *sigs);
+ if (!sigs)
+ {
+ log_error (_("error allocating memory: %s\n"),
+ gpg_strerror (gpg_error_from_syserror ()));
+ return 0;
+ }
+
+ i = 0;
+ for (n = kb; n; n = n->next)
+ {
+ if (is_deleted_kbnode (n))
+ continue;
+
+ if (n->pkt->pkttype != PKT_SIGNATURE)
+ continue;
+
+ sigs[i] = n;
+ i ++;
+ }
+ log_assert (i == nsigs);
+
+ qsort (sigs, nsigs, sizeof (sigs[0]), sig_comparison);
+
+ last_i = 0;
+ for (i = 1; i < nsigs; i ++)
+ {
+ log_assert (sigs[last_i]);
+ log_assert (sigs[last_i]->pkt->pkttype == PKT_SIGNATURE);
+ log_assert (sigs[i]);
+ log_assert (sigs[i]->pkt->pkttype == PKT_SIGNATURE);
+
+ if (sig_comparison (&sigs[last_i], &sigs[i]) == 0)
+ /* They are the same. Kill the latter. */
+ {
+ if (DBG_PACKET)
+ {
+ PKT_signature *sig = sigs[i]->pkt->pkt.signature;
+
+ log_debug ("Signature appears multiple times, "
+ "deleting duplicate:\n");
+ log_debug (" sig: class 0x%x, issuer: %s,"
+ " timestamp: %s (%lld), digest: %02x %02x\n",
+ sig->sig_class, keystr (sig->keyid),
+ isotimestamp (sig->timestamp),
+ (long long) sig->timestamp,
+ sig->digest_start[0], sig->digest_start[1]);
+ }
+
+ /* Remove sigs[i] from the keyblock. */
+ {
+ KBNODE z, *prevp;
+ int to_kill = last_i;
+ last_i = i;
+
+ for (prevp = &kb, z = kb; z; prevp = &z->next, z = z->next)
+ if (z == sigs[to_kill])
+ break;
+
+ *prevp = sigs[to_kill]->next;
+
+ sigs[to_kill]->next = NULL;
+ release_kbnode (sigs[to_kill]);
+ sigs[to_kill] = NULL;
+
+ dups ++;
+ modified = 1;
+ }
+ }
+ else
+ last_i = i;
+ }
+
+ xfree (sigs);
+ }
+
+ /* Make sure the sigs occur after the component (public key, subkey,
+ user id) that they sign. */
+ issuer = NULL;
+ last_printed_component = NULL;
+ for (n_prevp = &kb, n = kb;
+ n;
+ /* If we moved n, then n_prevp is need valid. */
+ n_prevp = (n->next == n_next ? &n->next : n_prevp), n = n_next)
+ {
+ PACKET *p;
+ int processed_current_component;
+ PKT_signature *sig;
+ int rc;
+ int dump_sig_params = 0;
+
+ n_next = n->next;
+
+ if (is_deleted_kbnode (n))
+ continue;
+
+ p = n->pkt;
+
+ if (issuer && issuer != pk)
+ {
+ free_public_key (issuer);
+ issuer = NULL;
+ }
+
+ xfree (pending_desc);
+ pending_desc = NULL;
+
+ switch (p->pkttype)
+ {
+ case PKT_PUBLIC_KEY:
+ log_assert (p->pkt.public_key == pk);
+ if (only_selected && ! (n->flag & NODFLG_SELKEY))
+ {
+ current_component = NULL;
+ break;
+ }
+
+ if (DBG_PACKET)
+ log_debug ("public key %s: timestamp: %s (%lld)\n",
+ pk_keyid_str (pk),
+ isotimestamp (pk->timestamp),
+ (long long) pk->timestamp);
+ current_component = n;
+ break;
+ case PKT_PUBLIC_SUBKEY:
+ if (only_selected && ! (n->flag & NODFLG_SELKEY))
+ {
+ current_component = NULL;
+ break;
+ }
+
+ if (DBG_PACKET)
+ log_debug ("subkey %s: timestamp: %s (%lld)\n",
+ pk_keyid_str (p->pkt.public_key),
+ isotimestamp (p->pkt.public_key->timestamp),
+ (long long) p->pkt.public_key->timestamp);
+ current_component = n;
+ break;
+ case PKT_USER_ID:
+ if (only_selected && ! (n->flag & NODFLG_SELUID))
+ {
+ current_component = NULL;
+ break;
+ }
+
+ if (DBG_PACKET)
+ log_debug ("user id: %s\n",
+ p->pkt.user_id->attrib_data
+ ? "[ photo id ]"
+ : p->pkt.user_id->name);
+ current_component = n;
+ break;
+ case PKT_SIGNATURE:
+ if (! current_component)
+ /* The current component is not selected, don't check the
+ sigs under it. */
+ break;
+
+ sig = n->pkt->pkt.signature;
+
+ pending_desc = xasprintf (" sig: class: 0x%x, issuer: %s,"
+ " timestamp: %s (%lld), digest: %02x %02x",
+ sig->sig_class,
+ keystr (sig->keyid),
+ isotimestamp (sig->timestamp),
+ (long long) sig->timestamp,
+ sig->digest_start[0], sig->digest_start[1]);
+
+
+ if (keyid_cmp (pk_keyid (pk), sig->keyid) == 0)
+ issuer = pk;
+ else /* Issuer is a different key. */
+ {
+ if (only_selfsigs)
+ continue;
+
+ issuer = xmalloc (sizeof (*issuer));
+ err = get_pubkey (ctrl, issuer, sig->keyid);
+ if (err)
+ {
+ xfree (issuer);
+ issuer = NULL;
+ if (DBG_PACKET)
+ {
+ if (pending_desc)
+ log_debug ("%s", pending_desc);
+ log_debug (" Can't check signature allegedly"
+ " issued by %s: %s\n",
+ keystr (sig->keyid), gpg_strerror (err));
+ }
+ missing_issuer ++;
+ break;
+ }
+ }
+
+ if ((err = openpgp_pk_test_algo (sig->pubkey_algo)))
+ {
+ if (DBG_PACKET && pending_desc)
+ log_debug ("%s", pending_desc);
+ log_info (_("can't check signature with unsupported"
+ " public-key algorithm (%d): %s.\n"),
+ sig->pubkey_algo, gpg_strerror (err));
+ break;
+ }
+ if ((err = openpgp_md_test_algo (sig->digest_algo)))
+ {
+ if (DBG_PACKET && pending_desc)
+ log_debug ("%s", pending_desc);
+ log_info (_("can't check signature with unsupported"
+ " message-digest algorithm %d: %s.\n"),
+ sig->digest_algo, gpg_strerror (err));
+ break;
+ }
+
+ /* We iterate over the keyblock. Most likely, the matching
+ component is the current component so always try that
+ first. */
+ processed_current_component = 0;
+ for (n2 = current_component;
+ n2;
+ n2 = (processed_current_component ? n2->next : kb),
+ processed_current_component = 1)
+ if (is_deleted_kbnode (n2))
+ continue;
+ else if (processed_current_component && n2 == current_component)
+ /* Don't process it twice. */
+ continue;
+ else
+ {
+ err = check_signature_over_key_or_uid (ctrl,
+ issuer, sig, kb, n2->pkt,
+ NULL, NULL);
+ if (! err)
+ break;
+ }
+
+ /* n/sig is a signature and n2 is the component (public key,
+ subkey or user id) that it signs, if any.
+ current_component is that component that it appears to
+ apply to (according to the ordering). */
+
+ if (current_component == n2)
+ {
+ if (DBG_PACKET)
+ {
+ log_debug ("%s", pending_desc);
+ log_debug (" Good signature over last key or uid!\n");
+ }
+
+ rc = 0;
+ }
+ else if (n2)
+ {
+ log_assert (n2->pkt->pkttype == PKT_USER_ID
+ || n2->pkt->pkttype == PKT_PUBLIC_KEY
+ || n2->pkt->pkttype == PKT_PUBLIC_SUBKEY);
+
+ if (DBG_PACKET)
+ {
+ log_debug ("%s", pending_desc);
+ log_debug (" Good signature out of order!"
+ " (Over %s (%d) '%s')\n",
+ n2->pkt->pkttype == PKT_USER_ID
+ ? "user id"
+ : n2->pkt->pkttype == PKT_PUBLIC_SUBKEY
+ ? "subkey"
+ : "primary key",
+ n2->pkt->pkttype,
+ n2->pkt->pkttype == PKT_USER_ID
+ ? n2->pkt->pkt.user_id->name
+ : pk_keyid_str (n2->pkt->pkt.public_key));
+ }
+
+ /* Reorder the packets: move the signature n to be just
+ after n2. */
+
+ /* Unlink the signature. */
+ log_assert (n_prevp);
+ *n_prevp = n->next;
+
+ /* Insert the sig immediately after the component. */
+ n->next = n2->next;
+ n2->next = n;
+
+ reordered ++;
+ modified = 1;
+
+ rc = 0;
+ }
+ else
+ {
+ if (DBG_PACKET)
+ {
+ log_debug ("%s", pending_desc);
+ log_debug (" Bad signature.\n");
+ }
+
+ if (DBG_PACKET)
+ dump_sig_params = 1;
+
+ bad_signature ++;
+
+ rc = GPG_ERR_BAD_SIGNATURE;
+ }
+
+ /* We don't cache the result here, because we haven't
+ completely checked that the signature is legitimate. For
+ instance, if we have a revocation certificate on Alice's
+ key signed by Bob, the signature may be good, but we
+ haven't checked that Bob is a designated revoker. */
+ /* cache_sig_result (sig, rc); */
+
+ {
+ int has_selfsig = 0;
+ if (! rc && issuer == pk)
+ {
+ if (n2->pkt->pkttype == PKT_PUBLIC_KEY
+ && (/* Direct key signature. */
+ sig->sig_class == 0x1f
+ /* Key revocation signature. */
+ || sig->sig_class == 0x20))
+ has_selfsig = 1;
+ if (n2->pkt->pkttype == PKT_PUBLIC_SUBKEY
+ && (/* Subkey binding sig. */
+ sig->sig_class == 0x18
+ /* Subkey revocation sig. */
+ || sig->sig_class == 0x28))
+ has_selfsig = 1;
+ if (n2->pkt->pkttype == PKT_USER_ID
+ && (/* Certification sigs. */
+ sig->sig_class == 0x10
+ || sig->sig_class == 0x11
+ || sig->sig_class == 0x12
+ || sig->sig_class == 0x13
+ /* Certification revocation sig. */
+ || sig->sig_class == 0x30))
+ has_selfsig = 1;
+ }
+
+ if ((n2 && n2 != last_printed_component)
+ || (! n2 && last_printed_component != current_component))
+ {
+ int is_reordered = n2 && n2 != current_component;
+ if (n2)
+ last_printed_component = n2;
+ else
+ last_printed_component = current_component;
+
+ if (!modified)
+ ;
+ else if (last_printed_component->pkt->pkttype == PKT_USER_ID)
+ {
+ tty_fprintf (fp, "uid ");
+ tty_print_utf8_string2 (fp,
+ last_printed_component
+ ->pkt->pkt.user_id->name,
+ last_printed_component
+ ->pkt->pkt.user_id->len, 0);
+ }
+ else if (last_printed_component->pkt->pkttype
+ == PKT_PUBLIC_KEY)
+ tty_fprintf (fp, "pub %s",
+ pk_keyid_str (last_printed_component
+ ->pkt->pkt.public_key));
+ else
+ tty_fprintf (fp, "sub %s",
+ pk_keyid_str (last_printed_component
+ ->pkt->pkt.public_key));
+
+ if (modified)
+ {
+ if (is_reordered)
+ tty_fprintf (fp, _(" (reordered signatures follow)"));
+ if (mode > 0)
+ log_printf ("\n");
+ else
+ tty_fprintf (fp, "\n");
+ }
+ }
+
+ if (modified)
+ keyedit_print_one_sig (ctrl, fp, rc, kb, n, NULL, NULL, NULL,
+ has_selfsig, 0, only_selfsigs);
+ }
+
+ if (dump_sig_params)
+ {
+ int i;
+
+ for (i = 0; i < pubkey_get_nsig (sig->pubkey_algo); i ++)
+ {
+ char buffer[1024];
+ size_t len;
+ char *printable;
+ gcry_mpi_print (GCRYMPI_FMT_USG,
+ buffer, sizeof (buffer), &len,
+ sig->data[i]);
+ printable = bin2hex (buffer, len, NULL);
+ log_debug (" %d: %s\n", i, printable);
+ xfree (printable);
+ }
+ }
+ break;
+ default:
+ if (DBG_PACKET)
+ log_debug ("unhandled packet: %d\n", p->pkttype);
+ break;
+ }
+ }
+
+ xfree (pending_desc);
+ pending_desc = NULL;
+
+ if (issuer != pk)
+ free_public_key (issuer);
+ issuer = NULL;
+
+ /* Identify keys / uids that don't have a self-sig. */
+ {
+ int has_selfsig = 0;
+ PACKET *p;
+ PKT_signature *sig;
+
+ current_component = NULL;
+ for (n = kb; n; n = n->next)
+ {
+ if (is_deleted_kbnode (n))
+ continue;
+
+ p = n->pkt;
+
+ switch (p->pkttype)
+ {
+ case PKT_PUBLIC_KEY:
+ case PKT_PUBLIC_SUBKEY:
+ case PKT_USER_ID:
+ if (current_component && ! has_selfsig)
+ missing_selfsig ++;
+ current_component = n;
+ has_selfsig = 0;
+ break;
+
+ case PKT_SIGNATURE:
+ if (! current_component || has_selfsig)
+ break;
+
+ sig = n->pkt->pkt.signature;
+
+ if (! (sig->flags.checked && sig->flags.valid))
+ break;
+
+ if (keyid_cmp (pk_keyid (pk), sig->keyid) != 0)
+ /* Different issuer, couldn't be a self-sig. */
+ break;
+
+ if (current_component->pkt->pkttype == PKT_PUBLIC_KEY
+ && (/* Direct key signature. */
+ sig->sig_class == 0x1f
+ /* Key revocation signature. */
+ || sig->sig_class == 0x20))
+ has_selfsig = 1;
+ if (current_component->pkt->pkttype == PKT_PUBLIC_SUBKEY
+ && (/* Subkey binding sig. */
+ sig->sig_class == 0x18
+ /* Subkey revocation sig. */
+ || sig->sig_class == 0x28))
+ has_selfsig = 1;
+ if (current_component->pkt->pkttype == PKT_USER_ID
+ && (/* Certification sigs. */
+ sig->sig_class == 0x10
+ || sig->sig_class == 0x11
+ || sig->sig_class == 0x12
+ || sig->sig_class == 0x13
+ /* Certification revocation sig. */
+ || sig->sig_class == 0x30))
+ has_selfsig = 1;
+
+ break;
+
+ default:
+ if (current_component && ! has_selfsig)
+ missing_selfsig ++;
+ current_component = NULL;
+ }
+ }
+ }
+
+ if (dups || missing_issuer || bad_signature || reordered)
+ tty_fprintf (fp, _("key %s:\n"), pk_keyid_str (pk));
+
+ if (dups)
+ tty_fprintf (fp,
+ ngettext ("%d duplicate signature removed\n",
+ "%d duplicate signatures removed\n", dups), dups);
+ if (missing_issuer)
+ tty_fprintf (fp,
+ ngettext ("%d signature not checked due to a missing key\n",
+ "%d signatures not checked due to missing keys\n",
+ missing_issuer), missing_issuer);
+ if (bad_signature)
+ tty_fprintf (fp,
+ ngettext ("%d bad signature\n",
+ "%d bad signatures\n",
+ bad_signature), bad_signature);
+ if (reordered)
+ tty_fprintf (fp,
+ ngettext ("%d signature reordered\n",
+ "%d signatures reordered\n",
+ reordered), reordered);
+
+ if (only_selfsigs && (bad_signature || reordered))
+ tty_fprintf (fp, _("Warning: errors found and only checked self-signatures,"
+ " run '%s' to check all signatures.\n"), "check");
+
+ return modified;
+}
diff --git a/g10/key-check.h b/g10/key-check.h
new file mode 100644
index 0000000..9f7886c
--- /dev/null
+++ b/g10/key-check.h
@@ -0,0 +1,28 @@
+/* key-check.h - Detect and fix various problems with keys
+ * Copyright (C) 2017 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 <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef GNUPG_G10_PACKET_TOOLS_H
+#define GNUPG_G10_PACKET_TOOLS_H
+
+#include "gpg.h"
+
+int key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb,
+ int only_selected, int only_selfsigs);
+
+#endif /* GNUPG_G10_PACKET_TOOLS_H */
diff --git a/g10/keydb.h b/g10/keydb.h
index 1da93a7..f793ada 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -119,13 +119,14 @@ union pref_hint
/* Constants to describe from where a key was fetched or updated. */
enum
{
- KEYSRC_UNKNOWN = 0,
- KEYSRC_FILE = 1, /* Direct import from a file. */
- KEYSRC_KS = 2, /* Public keyserver. */
- KEYSRC_PREF_KS = 3, /* Preferred keysrver. */
- KEYSRC_WKD = 4, /* Web Key Directory. */
- KEYSRC_WKD_SD = 5, /* Web Key Directory but from a sub domain. */
- KEYSRC_DANE = 6 /* OpenPGP DANE. */
+ KEYORG_UNKNOWN = 0,
+ KEYORG_KS = 1, /* Public keyserver. */
+ KEYORG_KS_PREF = 2, /* Preferred keysrver. */
+ KEYORG_DANE = 3, /* OpenPGP DANE. */
+ KEYORG_WKD = 4, /* Web Key Directory. */
+ KEYORG_URL = 5, /* Trusted URL. */
+ KEYORG_FILE = 6, /* Trusted file. */
+ KEYORG_SELF = 7 /* We generated it. */
};
@@ -318,10 +319,10 @@ int get_pubkey_byname (ctrl_t ctrl,
/* Likewise, but only return the best match if NAME resembles a mail
* address. */
-int get_best_pubkey_byname (ctrl_t ctrl,
- GETKEY_CTX *retctx, PKT_public_key *pk,
- const char *name, KBNODE *ret_keyblock,
- int include_unusable, int no_akl);
+gpg_error_t get_best_pubkey_byname (ctrl_t ctrl,
+ GETKEY_CTX *retctx, PKT_public_key *pk,
+ const char *name, KBNODE *ret_keyblock,
+ int include_unusable, int no_akl);
/* Get a public key directly from file FNAME. */
gpg_error_t get_pubkey_fromfile (ctrl_t ctrl,
@@ -351,6 +352,8 @@ const char *parse_def_secret_key (ctrl_t ctrl);
/* Look up a secret key. */
gpg_error_t get_seckey_default (ctrl_t ctrl, PKT_public_key *pk);
+gpg_error_t get_seckey_default_or_card (ctrl_t ctrl, PKT_public_key *pk,
+ const byte *fpr, size_t fpr_len);
/* Search for keys matching some criteria. */
gpg_error_t getkey_bynames (ctrl_t ctrl,
@@ -394,6 +397,8 @@ char *get_user_id_byfpr_native (ctrl_t ctrl, const byte *fpr);
void release_akl(void);
int parse_auto_key_locate(char *options);
+int parse_key_origin (char *string);
+const char *key_origin_string (int origin);
/*-- keyid.c --*/
int pubkey_letter( int algo );
@@ -454,6 +459,13 @@ u32 keyid_from_fingerprint (ctrl_t ctrl, 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 );
+
+/* Convert an UTC TIMESTAMP into an UTC yyyy-mm-dd string. Return
+ * that string. The caller should pass a buffer with at least a size
+ * of MK_DATESTR_SIZE. */
+char *mk_datestr (char *buffer, size_t bufsize, u32 timestamp);
+#define MK_DATESTR_SIZE 11
+
const char *datestr_from_pk( PKT_public_key *pk );
const char *datestr_from_sig( PKT_signature *sig );
const char *expirestr_from_pk( PKT_public_key *pk );
diff --git a/g10/keyedit.c b/g10/keyedit.c
index ba08d88..e221b32 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -48,6 +48,8 @@
#include "call-agent.h"
#include "../common/host2net.h"
#include "tofu.h"
+#include "key-check.h"
+#include "keyedit.h"
static void show_prefs (PKT_user_id * uid, PKT_signature * selfsig,
int verbose);
@@ -71,7 +73,7 @@ static int menu_clean (ctrl_t ctrl, kbnode_t 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 gpg_error_t menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
- int force_mainkey, u32 newexpiration);
+ int unattended, u32 newexpiration);
static int menu_changeusage (ctrl_t ctrl, kbnode_t keyblock);
static int menu_backsign (ctrl_t ctrl, kbnode_t pub_keyblock);
static int menu_set_primary_uid (ctrl_t ctrl, kbnode_t pub_keyblock);
@@ -105,17 +107,6 @@ 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_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;
@@ -201,10 +192,11 @@ print_and_check_one_sig_colon (ctrl_t ctrl, kbnode_t keyblock, kbnode_t node,
* packet. With EXTENDED set all possible signature list options will
* always be printed.
*/
-static int
-print_one_sig (ctrl_t ctrl, int rc, kbnode_t keyblock, kbnode_t node,
- int *inv_sigs, int *no_key, int *oth_err,
- int is_selfsig, int print_without_key, int extended)
+int
+keyedit_print_one_sig (ctrl_t ctrl, estream_t fp,
+ int rc, kbnode_t keyblock, kbnode_t node,
+ int *inv_sigs, int *no_key, int *oth_err,
+ int is_selfsig, int print_without_key, int extended)
{
PKT_signature *sig = node->pkt->pkt.signature;
int sigrc;
@@ -241,7 +233,7 @@ print_one_sig (ctrl_t ctrl, int rc, kbnode_t keyblock, kbnode_t node,
}
if (sigrc != '?' || print_without_key)
{
- tty_printf ("%s%c%c %c%c%c%c%c%c %s %s",
+ tty_fprintf (fp, "%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 <
@@ -257,38 +249,41 @@ print_one_sig (ctrl_t ctrl, int rc, kbnode_t keyblock, kbnode_t node,
keystr (sig->keyid),
datestr_from_sig (sig));
if ((opt.list_options & LIST_SHOW_SIG_EXPIRE) || extended )
- tty_printf (" %s", expirestr_from_sig (sig));
- tty_printf (" ");
+ tty_fprintf (fp, " %s", expirestr_from_sig (sig));
+ tty_fprintf (fp, " ");
if (sigrc == '%')
- tty_printf ("[%s] ", gpg_strerror (rc));
+ tty_fprintf (fp, "[%s] ", gpg_strerror (rc));
else if (sigrc == '?')
;
else if (is_selfsig)
{
- tty_printf (is_rev ? _("[revocation]") : _("[self-signature]"));
+ tty_fprintf (fp, is_rev ? _("[revocation]") : _("[self-signature]"));
if (extended && sig->flags.chosen_selfsig)
- tty_printf ("*");
+ tty_fprintf (fp, "*");
}
else
{
size_t n;
char *p = get_user_id (ctrl, sig->keyid, &n);
- tty_print_utf8_string2 (NULL, p, n,
+ tty_print_utf8_string2 (fp, p, n,
opt.screen_columns - keystrlen () - 26 -
((opt.
list_options & LIST_SHOW_SIG_EXPIRE) ? 11
: 0));
xfree (p);
}
- tty_printf ("\n");
+ if (fp == log_get_stream ())
+ log_printf ("\n");
+ else
+ tty_fprintf (fp, "\n");
if (sig->flags.policy_url
&& ((opt.list_options & LIST_SHOW_POLICY_URLS) || extended))
- show_policy_url (sig, 3, -1);
+ show_policy_url (sig, 3, (!fp? -1 : fp == log_get_stream ()? 1 : 0));
if (sig->flags.notation
&& ((opt.list_options & LIST_SHOW_NOTATIONS) || extended))
- show_notation (sig, 3, -1,
+ show_notation (sig, 3, (!fp? -1 : fp == log_get_stream ()? 1 : 0),
((opt.
list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0) +
((opt.
@@ -296,7 +291,7 @@ print_one_sig (ctrl_t ctrl, int rc, kbnode_t keyblock, kbnode_t node,
if (sig->flags.pref_ks
&& ((opt.list_options & LIST_SHOW_KEYSERVER_URLS) || extended))
- show_keyserver_url (sig, 3, -1);
+ show_keyserver_url (sig, 3, (!fp? -1 : fp == log_get_stream ()? 1 : 0));
if (extended)
{
@@ -305,12 +300,12 @@ print_one_sig (ctrl_t ctrl, int rc, kbnode_t keyblock, kbnode_t node,
s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PRIMARY_UID, NULL);
if (s && *s)
- tty_printf (" [primary]\n");
+ tty_fprintf (fp, " [primary]\n");
s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL);
if (s && buf32_to_u32 (s))
- tty_printf (" [expires: %s]\n",
- isotimestamp (pk->timestamp + buf32_to_u32 (s)));
+ tty_fprintf (fp, " [expires: %s]\n",
+ isotimestamp (pk->timestamp + buf32_to_u32 (s)));
}
}
@@ -326,618 +321,9 @@ print_and_check_one_sig (ctrl_t ctrl, kbnode_t keyblock, kbnode_t node,
int rc;
rc = check_key_signature (ctrl, keyblock, node, is_selfsig);
- return print_one_sig (ctrl, rc,
- keyblock, node, inv_sigs, no_key, oth_err,
- *is_selfsig, print_without_key, extended);
-}
-
-
-
-/* Order two signatures. The actual ordering isn't important. Our
- goal is to ensure that identical signatures occur together. */
-static int
-sig_comparison (const void *av, const void *bv)
-{
- const KBNODE an = *(const KBNODE *) av;
- const KBNODE bn = *(const KBNODE *) bv;
- const PKT_signature *a;
- const PKT_signature *b;
- int ndataa;
- int ndatab;
- int i;
-
- log_assert (an->pkt->pkttype == PKT_SIGNATURE);
- log_assert (bn->pkt->pkttype == PKT_SIGNATURE);
-
- a = an->pkt->pkt.signature;
- b = bn->pkt->pkt.signature;
-
- if (a->digest_algo < b->digest_algo)
- return -1;
- if (a->digest_algo > b->digest_algo)
- return 1;
-
- ndataa = pubkey_get_nsig (a->pubkey_algo);
- ndatab = pubkey_get_nsig (b->pubkey_algo);
- if (ndataa != ndatab)
- return (ndataa < ndatab)? -1 : 1;
-
- for (i = 0; i < ndataa; i ++)
- {
- int c = gcry_mpi_cmp (a->data[i], b->data[i]);
- if (c != 0)
- return c;
- }
-
- /* Okay, they are equal. */
- return 0;
-}
-
-/* Perform a few sanity checks on a keyblock is okay and possibly
- repair some damage. Concretely:
-
- - Detect duplicate signatures and remove them.
-
- - Detect out of order signatures and relocate them (e.g., a sig
- over user id X located under subkey Y).
-
- Note: this function does not remove signatures that don't belong or
- components that are not signed! (Although it would be trivial to
- do so.)
-
- If ONLY_SELFSIGS is true, then this function only reorders self
- signatures (it still checks all signatures for duplicates,
- however).
-
- Returns 1 if the keyblock was modified, 0 otherwise. */
-static int
-check_all_keysigs (ctrl_t ctrl, kbnode_t kb,
- int only_selected, int only_selfsigs)
-{
- gpg_error_t err;
- PKT_public_key *pk;
- KBNODE n, n_next, *n_prevp, n2;
- char *pending_desc = NULL;
- PKT_public_key *issuer;
- KBNODE last_printed_component;
- KBNODE current_component = NULL;
- int dups = 0;
- int missing_issuer = 0;
- int reordered = 0;
- int bad_signature = 0;
- int missing_selfsig = 0;
- int modified = 0;
-
- log_assert (kb->pkt->pkttype == PKT_PUBLIC_KEY);
- pk = kb->pkt->pkt.public_key;
-
- /* First we look for duplicates. */
- {
- int nsigs;
- kbnode_t *sigs;
- int i;
- int last_i;
-
- /* Count the sigs. */
- for (nsigs = 0, n = kb; n; n = n->next)
- {
- if (is_deleted_kbnode (n))
- continue;
- else if (n->pkt->pkttype == PKT_SIGNATURE)
- nsigs ++;
- }
-
- if (!nsigs)
- return 0; /* No signatures at all. */
-
- /* Add them all to the SIGS array. */
- sigs = xtrycalloc (nsigs, sizeof *sigs);
- if (!sigs)
- {
- log_error (_("error allocating memory: %s\n"),
- gpg_strerror (gpg_error_from_syserror ()));
- return 0;
- }
-
- i = 0;
- for (n = kb; n; n = n->next)
- {
- if (is_deleted_kbnode (n))
- continue;
-
- if (n->pkt->pkttype != PKT_SIGNATURE)
- continue;
-
- sigs[i] = n;
- i ++;
- }
- log_assert (i == nsigs);
-
- qsort (sigs, nsigs, sizeof (sigs[0]), sig_comparison);
-
- last_i = 0;
- for (i = 1; i < nsigs; i ++)
- {
- log_assert (sigs[last_i]);
- log_assert (sigs[last_i]->pkt->pkttype == PKT_SIGNATURE);
- log_assert (sigs[i]);
- log_assert (sigs[i]->pkt->pkttype == PKT_SIGNATURE);
-
- if (sig_comparison (&sigs[last_i], &sigs[i]) == 0)
- /* They are the same. Kill the latter. */
- {
- if (DBG_PACKET)
- {
- PKT_signature *sig = sigs[i]->pkt->pkt.signature;
-
- log_debug ("Signature appears multiple times, "
- "deleting duplicate:\n");
- log_debug (" sig: class 0x%x, issuer: %s,"
- " timestamp: %s (%lld), digest: %02x %02x\n",
- sig->sig_class, keystr (sig->keyid),
- isotimestamp (sig->timestamp),
- (long long) sig->timestamp,
- sig->digest_start[0], sig->digest_start[1]);
- }
-
- /* Remove sigs[i] from the keyblock. */
- {
- KBNODE z, *prevp;
- int to_kill = last_i;
- last_i = i;
-
- for (prevp = &kb, z = kb; z; prevp = &z->next, z = z->next)
- if (z == sigs[to_kill])
- break;
-
- *prevp = sigs[to_kill]->next;
-
- sigs[to_kill]->next = NULL;
- release_kbnode (sigs[to_kill]);
- sigs[to_kill] = NULL;
-
- dups ++;
- modified = 1;
- }
- }
- else
- last_i = i;
- }
-
- xfree (sigs);
- }
-
- /* Make sure the sigs occur after the component (public key, subkey,
- user id) that they sign. */
- issuer = NULL;
- last_printed_component = NULL;
- for (n_prevp = &kb, n = kb;
- n;
- /* If we moved n, then n_prevp is need valid. */
- n_prevp = (n->next == n_next ? &n->next : n_prevp), n = n_next)
- {
- PACKET *p;
- int processed_current_component;
- PKT_signature *sig;
- int rc;
- int dump_sig_params = 0;
-
- n_next = n->next;
-
- if (is_deleted_kbnode (n))
- continue;
-
- p = n->pkt;
-
- if (issuer && issuer != pk)
- {
- free_public_key (issuer);
- issuer = NULL;
- }
-
- xfree (pending_desc);
- pending_desc = NULL;
-
- switch (p->pkttype)
- {
- case PKT_PUBLIC_KEY:
- log_assert (p->pkt.public_key == pk);
- if (only_selected && ! (n->flag & NODFLG_SELKEY))
- {
- current_component = NULL;
- break;
- }
-
- if (DBG_PACKET)
- log_debug ("public key %s: timestamp: %s (%lld)\n",
- pk_keyid_str (pk),
- isotimestamp (pk->timestamp),
- (long long) pk->timestamp);
- current_component = n;
- break;
- case PKT_PUBLIC_SUBKEY:
- if (only_selected && ! (n->flag & NODFLG_SELKEY))
- {
- current_component = NULL;
- break;
- }
-
- if (DBG_PACKET)
- log_debug ("subkey %s: timestamp: %s (%lld)\n",
- pk_keyid_str (p->pkt.public_key),
- isotimestamp (p->pkt.public_key->timestamp),
- (long long) p->pkt.public_key->timestamp);
- current_component = n;
- break;
- case PKT_USER_ID:
- if (only_selected && ! (n->flag & NODFLG_SELUID))
- {
- current_component = NULL;
- break;
- }
-
- if (DBG_PACKET)
- log_debug ("user id: %s\n",
- p->pkt.user_id->attrib_data
- ? "[ photo id ]"
- : p->pkt.user_id->name);
- current_component = n;
- break;
- case PKT_SIGNATURE:
- if (! current_component)
- /* The current component is not selected, don't check the
- sigs under it. */
- break;
-
- sig = n->pkt->pkt.signature;
-
- pending_desc = xasprintf (" sig: class: 0x%x, issuer: %s,"
- " timestamp: %s (%lld), digest: %02x %02x",
- sig->sig_class,
- keystr (sig->keyid),
- isotimestamp (sig->timestamp),
- (long long) sig->timestamp,
- sig->digest_start[0], sig->digest_start[1]);
-
-
- if (keyid_cmp (pk_keyid (pk), sig->keyid) == 0)
- issuer = pk;
- else /* Issuer is a different key. */
- {
- if (only_selfsigs)
- continue;
-
- issuer = xmalloc (sizeof (*issuer));
- err = get_pubkey (ctrl, issuer, sig->keyid);
- if (err)
- {
- xfree (issuer);
- issuer = NULL;
- if (DBG_PACKET)
- {
- if (pending_desc)
- log_debug ("%s", pending_desc);
- log_debug (" Can't check signature allegedly"
- " issued by %s: %s\n",
- keystr (sig->keyid), gpg_strerror (err));
- }
- missing_issuer ++;
- break;
- }
- }
-
- if ((err = openpgp_pk_test_algo (sig->pubkey_algo)))
- {
- if (DBG_PACKET && pending_desc)
- log_debug ("%s", pending_desc);
- tty_printf (_("can't check signature with unsupported"
- " public-key algorithm (%d): %s.\n"),
- sig->pubkey_algo, gpg_strerror (err));
- break;
- }
- if ((err = openpgp_md_test_algo (sig->digest_algo)))
- {
- if (DBG_PACKET && pending_desc)
- log_debug ("%s", pending_desc);
- tty_printf (_("can't check signature with unsupported"
- " message-digest algorithm %d: %s.\n"),
- sig->digest_algo, gpg_strerror (err));
- break;
- }
-
- /* We iterate over the keyblock. Most likely, the matching
- component is the current component so always try that
- first. */
- processed_current_component = 0;
- for (n2 = current_component;
- n2;
- n2 = (processed_current_component ? n2->next : kb),
- processed_current_component = 1)
- if (is_deleted_kbnode (n2))
- continue;
- else if (processed_current_component && n2 == current_component)
- /* Don't process it twice. */
- continue;
- else
- {
- err = check_signature_over_key_or_uid (ctrl,
- issuer, sig, kb, n2->pkt,
- NULL, NULL);
- if (! err)
- break;
- }
-
- /* n/sig is a signature and n2 is the component (public key,
- subkey or user id) that it signs, if any.
- current_component is that component that it appears to
- apply to (according to the ordering). */
-
- if (current_component == n2)
- {
- if (DBG_PACKET)
- {
- log_debug ("%s", pending_desc);
- log_debug (" Good signature over last key or uid!\n");
- }
-
- rc = 0;
- }
- else if (n2)
- {
- log_assert (n2->pkt->pkttype == PKT_USER_ID
- || n2->pkt->pkttype == PKT_PUBLIC_KEY
- || n2->pkt->pkttype == PKT_PUBLIC_SUBKEY);
-
- if (DBG_PACKET)
- {
- log_debug ("%s", pending_desc);
- log_debug (" Good signature out of order!"
- " (Over %s (%d) '%s')\n",
- n2->pkt->pkttype == PKT_USER_ID
- ? "user id"
- : n2->pkt->pkttype == PKT_PUBLIC_SUBKEY
- ? "subkey"
- : "primary key",
- n2->pkt->pkttype,
- n2->pkt->pkttype == PKT_USER_ID
- ? n2->pkt->pkt.user_id->name
- : pk_keyid_str (n2->pkt->pkt.public_key));
- }
-
- /* Reorder the packets: move the signature n to be just
- after n2. */
-
- /* Unlink the signature. */
- log_assert (n_prevp);
- *n_prevp = n->next;
-
- /* Insert the sig immediately after the component. */
- n->next = n2->next;
- n2->next = n;
-
- reordered ++;
- modified = 1;
-
- rc = 0;
- }
- else
- {
- if (DBG_PACKET)
- {
- log_debug ("%s", pending_desc);
- log_debug (" Bad signature.\n");
- }
-
- if (DBG_PACKET)
- dump_sig_params = 1;
-
- bad_signature ++;
-
- rc = GPG_ERR_BAD_SIGNATURE;
- }
-
- /* We don't cache the result here, because we haven't
- completely checked that the signature is legitimate. For
- instance, if we have a revocation certificate on Alice's
- key signed by Bob, the signature may be good, but we
- haven't checked that Bob is a designated revoker. */
- /* cache_sig_result (sig, rc); */
-
- {
- int has_selfsig = 0;
- if (! rc && issuer == pk)
- {
- if (n2->pkt->pkttype == PKT_PUBLIC_KEY
- && (/* Direct key signature. */
- sig->sig_class == 0x1f
- /* Key revocation signature. */
- || sig->sig_class == 0x20))
- has_selfsig = 1;
- if (n2->pkt->pkttype == PKT_PUBLIC_SUBKEY
- && (/* Subkey binding sig. */
- sig->sig_class == 0x18
- /* Subkey revocation sig. */
- || sig->sig_class == 0x28))
- has_selfsig = 1;
- if (n2->pkt->pkttype == PKT_USER_ID
- && (/* Certification sigs. */
- sig->sig_class == 0x10
- || sig->sig_class == 0x11
- || sig->sig_class == 0x12
- || sig->sig_class == 0x13
- /* Certification revocation sig. */
- || sig->sig_class == 0x30))
- has_selfsig = 1;
- }
-
- if ((n2 && n2 != last_printed_component)
- || (! n2 && last_printed_component != current_component))
- {
- int is_reordered = n2 && n2 != current_component;
- if (n2)
- last_printed_component = n2;
- else
- last_printed_component = current_component;
-
- if (!modified)
- ;
- else if (last_printed_component->pkt->pkttype == PKT_USER_ID)
- {
- tty_printf ("uid ");
- tty_print_utf8_string (last_printed_component
- ->pkt->pkt.user_id->name,
- last_printed_component
- ->pkt->pkt.user_id->len);
- }
- else if (last_printed_component->pkt->pkttype
- == PKT_PUBLIC_KEY)
- tty_printf ("pub %s",
- pk_keyid_str (last_printed_component
- ->pkt->pkt.public_key));
- else
- tty_printf ("sub %s",
- pk_keyid_str (last_printed_component
- ->pkt->pkt.public_key));
-
- if (modified)
- {
- if (is_reordered)
- tty_printf (_(" (reordered signatures follow)"));
- tty_printf ("\n");
- }
- }
-
- if (modified)
- print_one_sig (ctrl, rc, kb, n, NULL, NULL, NULL, has_selfsig,
- 0, only_selfsigs);
- }
-
- if (dump_sig_params)
- {
- int i;
-
- for (i = 0; i < pubkey_get_nsig (sig->pubkey_algo); i ++)
- {
- char buffer[1024];
- size_t len;
- char *printable;
- gcry_mpi_print (GCRYMPI_FMT_USG,
- buffer, sizeof (buffer), &len,
- sig->data[i]);
- printable = bin2hex (buffer, len, NULL);
- log_info (" %d: %s\n", i, printable);
- xfree (printable);
- }
- }
- break;
- default:
- if (DBG_PACKET)
- log_debug ("unhandled packet: %d\n", p->pkttype);
- break;
- }
- }
-
- xfree (pending_desc);
- pending_desc = NULL;
-
- if (issuer != pk)
- free_public_key (issuer);
- issuer = NULL;
-
- /* Identify keys / uids that don't have a self-sig. */
- {
- int has_selfsig = 0;
- PACKET *p;
- PKT_signature *sig;
-
- current_component = NULL;
- for (n = kb; n; n = n->next)
- {
- if (is_deleted_kbnode (n))
- continue;
-
- p = n->pkt;
-
- switch (p->pkttype)
- {
- case PKT_PUBLIC_KEY:
- case PKT_PUBLIC_SUBKEY:
- case PKT_USER_ID:
- if (current_component && ! has_selfsig)
- missing_selfsig ++;
- current_component = n;
- has_selfsig = 0;
- break;
-
- case PKT_SIGNATURE:
- if (! current_component || has_selfsig)
- break;
-
- sig = n->pkt->pkt.signature;
-
- if (! (sig->flags.checked && sig->flags.valid))
- break;
-
- if (keyid_cmp (pk_keyid (pk), sig->keyid) != 0)
- /* Different issuer, couldn't be a self-sig. */
- break;
-
- if (current_component->pkt->pkttype == PKT_PUBLIC_KEY
- && (/* Direct key signature. */
- sig->sig_class == 0x1f
- /* Key revocation signature. */
- || sig->sig_class == 0x20))
- has_selfsig = 1;
- if (current_component->pkt->pkttype == PKT_PUBLIC_SUBKEY
- && (/* Subkey binding sig. */
- sig->sig_class == 0x18
- /* Subkey revocation sig. */
- || sig->sig_class == 0x28))
- has_selfsig = 1;
- if (current_component->pkt->pkttype == PKT_USER_ID
- && (/* Certification sigs. */
- sig->sig_class == 0x10
- || sig->sig_class == 0x11
- || sig->sig_class == 0x12
- || sig->sig_class == 0x13
- /* Certification revocation sig. */
- || sig->sig_class == 0x30))
- has_selfsig = 1;
-
- break;
-
- default:
- if (current_component && ! has_selfsig)
- missing_selfsig ++;
- current_component = NULL;
- }
- }
- }
-
- if (dups || missing_issuer || bad_signature || reordered)
- tty_printf (_("key %s:\n"), pk_keyid_str (pk));
-
- if (dups)
- tty_printf (ngettext ("%d duplicate signature removed\n",
- "%d duplicate signatures removed\n", dups), dups);
- if (missing_issuer)
- tty_printf (ngettext ("%d signature not checked due to a missing key\n",
- "%d signatures not checked due to missing keys\n",
- missing_issuer), missing_issuer);
- if (bad_signature)
- tty_printf (ngettext ("%d bad signature\n",
- "%d bad signatures\n",
- bad_signature), bad_signature);
- if (reordered)
- tty_printf (ngettext ("%d signature reordered\n",
- "%d signatures reordered\n",
- reordered), reordered);
-
- if (only_selfsigs && (bad_signature || reordered))
- tty_printf (_("Warning: errors found and only checked self-signatures,"
- " run '%s' to check all signatures.\n"), "check");
-
- return modified;
+ return keyedit_print_one_sig (ctrl, NULL, rc,
+ keyblock, node, inv_sigs, no_key, oth_err,
+ *is_selfsig, print_without_key, extended);
}
@@ -1784,7 +1170,7 @@ fix_keyblock (ctrl_t ctrl, kbnode_t *keyblockp)
if (collapse_uids (keyblockp))
changed++;
- if (check_all_keysigs (ctrl, *keyblockp, 0, 1))
+ if (key_check_all_keysigs (ctrl, 1, *keyblockp, 0, 1))
changed++;
reorder_keyblock (*keyblockp);
/* If we modified the keyblock, make sure the flags are right. */
@@ -2231,9 +1617,9 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
break;
case cmdCHECK:
- if (check_all_keysigs (ctrl, keyblock,
- count_selected_uids (keyblock),
- !strcmp (arg_string, "selfsig")))
+ if (key_check_all_keysigs (ctrl, -1, keyblock,
+ count_selected_uids (keyblock),
+ !strcmp (arg_string, "selfsig")))
modified = 1;
break;
@@ -2314,7 +1700,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
if (RFC2440)
{
tty_printf (_("This command is not allowed while in %s mode.\n"),
- compliance_option_string ());
+ gnupg_compliance_option_string (opt.compliance));
break;
}
photo = 1;
@@ -3426,18 +2812,24 @@ keyedit_quick_addkey (ctrl_t ctrl, const char *fpr, const char *algostr,
}
-/* Unattended expiration setting function for the main key.
- *
+/* Unattended expiration setting function for the main key. If
+ * SUBKEYFPRS is not NULL and SUBKEYSFPRS[0] is neither NULL, it is
+ * expected to be an array of fingerprints for subkeys to change. It
+ * may also be an array which just one item "*" to indicate that all
+ * keys shall be set to that expiration date.
*/
void
-keyedit_quick_set_expire (ctrl_t ctrl, const char *fpr, const char *expirestr)
+keyedit_quick_set_expire (ctrl_t ctrl, const char *fpr, const char *expirestr,
+ char **subkeyfprs)
{
gpg_error_t err;
- kbnode_t keyblock;
+ kbnode_t keyblock, node;
KEYDB_HANDLE kdbhd;
int modified = 0;
PKT_public_key *pk;
u32 expire;
+ int primary_only = 0;
+ int idx;
#ifdef HAVE_W32_SYSTEM
/* See keyedit_menu for why we need this. */
@@ -3464,7 +2856,6 @@ keyedit_quick_set_expire (ctrl_t ctrl, const char *fpr, const char *expirestr)
goto leave;
}
-
expire = parse_expire_string (expirestr);
if (expire == (u32)-1 )
{
@@ -3475,8 +2866,78 @@ keyedit_quick_set_expire (ctrl_t ctrl, const char *fpr, const char *expirestr)
if (expire)
expire += make_timestamp ();
+ /* Check whether a subkey's expiration time shall be changed or the
+ * expiration time of all keys. */
+ if (!subkeyfprs || !subkeyfprs[0])
+ primary_only = 1;
+ else if ( !strcmp (subkeyfprs[0], "*") && !subkeyfprs[1])
+ {
+ /* Change all subkeys keys which have not been revoked and are
+ * not yet expired. */
+ merge_keys_and_selfsig (ctrl, keyblock);
+ for (node = keyblock; node; node = node->next)
+ {
+ if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+ && (pk = node->pkt->pkt.public_key)
+ && !pk->flags.revoked
+ && !pk->has_expired)
+ node->flag |= NODFLG_SELKEY;
+ }
+ }
+ else
+ {
+ /* Change specified subkeys. */
+ KEYDB_SEARCH_DESC desc;
+ byte fprbin[MAX_FINGERPRINT_LEN];
+ size_t fprlen;
+
+ err = 0;
+ merge_keys_and_selfsig (ctrl, keyblock);
+ for (idx=0; subkeyfprs[idx]; idx++)
+ {
+ int any = 0;
+
+ /* Parse the fingerprint. */
+ if (classify_user_id (subkeyfprs[idx], &desc, 1)
+ || !(desc.mode == KEYDB_SEARCH_MODE_FPR
+ || desc.mode == KEYDB_SEARCH_MODE_FPR20))
+ {
+ log_error (_("\"%s\" is not a proper fingerprint\n"),
+ subkeyfprs[idx] );
+ if (!err)
+ err = gpg_error (GPG_ERR_INV_NAME);
+ continue;
+ }
+
+ /* Set the flag for the matching non revoked subkey. */
+ for (node = keyblock; node; node = node->next)
+ {
+ if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+ && (pk = node->pkt->pkt.public_key)
+ && !pk->flags.revoked )
+ {
+ fingerprint_from_pk (pk, fprbin, &fprlen);
+ if (fprlen == 20 && !memcmp (fprbin, desc.u.fpr, 20))
+ {
+ node->flag |= NODFLG_SELKEY;
+ any = 1;
+ }
+ }
+ }
+ if (!any)
+ {
+ log_error (_("subkey \"%s\" not found\n"), subkeyfprs[idx]);
+ if (!err)
+ err = gpg_error (GPG_ERR_NOT_FOUND);
+ }
+ }
+
+ if (err)
+ goto leave;
+ }
+
/* Set the new expiration date. */
- err = menu_expire (ctrl, keyblock, 1, expire);
+ err = menu_expire (ctrl, keyblock, primary_only? 1 : 2, expire);
if (gpg_err_code (err) == GPG_ERR_TRUE)
modified = 1;
else if (err)
@@ -4901,30 +4362,34 @@ fail:
/* With FORCE_MAINKEY cleared this function handles the interactive
- * menu option "expire". With FORCE_MAINKEY set this functions only
+ * menu option "expire". With UNATTENDED set to 1 this function only
* sets the expiration date of the primary key to NEWEXPIRATION and
- * avoid all interactivity. Retirns 0 if nothing was done,
+ * avoid all interactivity; with a value of 2 only the flagged subkeys
+ * are set to NEWEXPIRATION. Returns 0 if nothing was done,
* GPG_ERR_TRUE if the key was modified, or any other error code. */
static gpg_error_t
menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
- int force_mainkey, u32 newexpiration)
+ int unattended, u32 newexpiration)
{
int signumber, rc;
u32 expiredate;
- int mainkey = 0;
+ int only_mainkey; /* Set if only the mainkey is to be updated. */
PKT_public_key *main_pk, *sub_pk;
PKT_user_id *uid;
kbnode_t node;
u32 keyid[2];
- if (force_mainkey)
+ if (unattended)
{
- mainkey = 1;
+ only_mainkey = (unattended == 1);
expiredate = newexpiration;
}
else
{
- int n1 = count_selected_keys (pub_keyblock);
+ int n1;
+
+ only_mainkey = 0;
+ n1 = count_selected_keys (pub_keyblock);
if (n1 > 1)
{
if (!cpr_get_answer_is_yes
@@ -4938,7 +4403,7 @@ menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
else
{
tty_printf (_("Changing expiration time for the primary key.\n"));
- mainkey = 1;
+ only_mainkey = 1;
no_primary_warning (pub_keyblock);
}
@@ -4960,8 +4425,10 @@ menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
}
else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
{
- if ((node->flag & NODFLG_SELKEY) && !force_mainkey)
+ if ((node->flag & NODFLG_SELKEY) && unattended != 1)
{
+ /* The flag is set and we do not want to set the
+ * expiration date only for the main key. */
sub_pk = node->pkt->pkt.public_key;
sub_pk->expiredate = expiredate;
}
@@ -4971,14 +4438,14 @@ menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
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))
+ && (only_mainkey || sub_pk))
{
PKT_signature *sig = node->pkt->pkt.signature;
if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
- && ((mainkey && uid
+ && ((only_mainkey && uid
&& uid->created && (sig->sig_class & ~3) == 0x10)
- || (!mainkey && sig->sig_class == 0x18))
+ || (!only_mainkey && sig->sig_class == 0x18))
&& sig->flags.chosen_selfsig)
{
/* This is a self-signature which is to be replaced. */
@@ -4987,15 +4454,15 @@ menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
signumber++;
- if ((mainkey && main_pk->version < 4)
- || (!mainkey && sub_pk->version < 4))
+ if ((only_mainkey && main_pk->version < 4)
+ || (!only_mainkey && sub_pk->version < 4))
{
log_info
(_("You can't change the expiration date of a v3 key\n"));
return gpg_error (GPG_ERR_LEGACY_KEY);
}
- if (mainkey)
+ if (only_mainkey)
rc = update_keysig_packet (ctrl,
&newsig, sig, main_pk, uid, NULL,
main_pk, keygen_add_key_expire,
diff --git a/g10/keyedit.h b/g10/keyedit.h
new file mode 100644
index 0000000..d1f453a
--- /dev/null
+++ b/g10/keyedit.h
@@ -0,0 +1,60 @@
+/* keyedit.h - Edit properties of a key
+ * Copyright (C) 1998-2010 Free Software Foundation, Inc.
+ * Copyright (C) 1998-2017 Werner Koch
+ * Copyright (C) 2015-2017 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 <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef GNUPG_G10_KEYEDIT_H
+#define GNUPG_G10_KEYEDIT_H
+
+#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_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. */
+
+/*-- keyedit.c --*/
+void keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
+ strlist_t commands, int quiet, int seckey_check );
+void keyedit_passwd (ctrl_t ctrl, const char *username);
+void keyedit_quick_adduid (ctrl_t ctrl, const char *username,
+ const char *newuid);
+void keyedit_quick_addkey (ctrl_t ctrl, const char *fpr, const char *algostr,
+ const char *usagestr, const char *expirestr);
+void keyedit_quick_revuid (ctrl_t ctrl, const char *username,
+ const char *uidtorev);
+void keyedit_quick_sign (ctrl_t ctrl, const char *fpr,
+ strlist_t uids, strlist_t locusr, int local);
+void keyedit_quick_set_expire (ctrl_t ctrl,
+ const char *fpr, const char *expirestr,
+ char **subkeyfprs);
+void keyedit_quick_set_primary (ctrl_t ctrl, const char *username,
+ const char *primaryuid);
+void show_basic_key_info (ctrl_t ctrl, kbnode_t keyblock);
+int keyedit_print_one_sig (ctrl_t ctrl, estream_t fp,
+ int rc, kbnode_t keyblock,
+ kbnode_t node, int *inv_sigs, int *no_key,
+ int *oth_err, int is_selfsig,
+ int print_without_key, int extended);
+
+#endif /* GNUPG_G10_KEYEDIT_H */
diff --git a/g10/keygen.c b/g10/keygen.c
index 0dfed63..6a3d323 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -4808,7 +4808,10 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
tty_printf (_("public and secret key created and signed.\n") );
tty_printf ("\n");
merge_keys_and_selfsig (ctrl, pub_root);
- list_keyblock_direct (ctrl, pub_root, 0, 1, 1, 1);
+
+ list_keyblock_direct (ctrl, pub_root, 0, 1,
+ opt.fingerprint || opt.with_fingerprint,
+ 1);
}
@@ -5041,6 +5044,8 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr,
err = agent_passwd (ctrl, hexgrip, desc, 1 /*=verify*/,
&cache_nonce, &passwd_nonce);
xfree (desc);
+ if (err)
+ goto leave;
}
/* Start creation. */
diff --git a/g10/keyid.c b/g10/keyid.c
index 24a5643..d733156 100644
--- a/g10/keyid.c
+++ b/g10/keyid.c
@@ -613,9 +613,13 @@ nbits_from_pk (PKT_public_key *pk)
}
-static const char *
-mk_datestr (char *buffer, time_t atime)
+/* Convert an UTC TIMESTAMP into an UTC yyyy-mm-dd string. Return
+ * that string. The caller should pass a buffer with at least a size
+ * of MK_DATESTR_SIZE. */
+char *
+mk_datestr (char *buffer, size_t bufsize, u32 timestamp)
{
+ time_t atime = timestamp;
struct tm *tp;
if (IS_INVALID_TIME_T (atime))
@@ -623,8 +627,8 @@ mk_datestr (char *buffer, time_t atime)
else
{
tp = gmtime (&atime);
- sprintf (buffer,"%04d-%02d-%02d",
- 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
+ snprintf (buffer, bufsize, "%04d-%02d-%02d",
+ 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
}
return buffer;
}
@@ -638,59 +642,51 @@ mk_datestr (char *buffer, time_t atime)
const char *
datestr_from_pk (PKT_public_key *pk)
{
- static char buffer[11+5];
- time_t atime = pk->timestamp;
+ static char buffer[MK_DATESTR_SIZE];
- return mk_datestr (buffer, atime);
+ return mk_datestr (buffer, sizeof buffer, pk->timestamp);
}
const char *
datestr_from_sig (PKT_signature *sig )
{
- static char buffer[11+5];
- time_t atime = sig->timestamp;
+ static char buffer[MK_DATESTR_SIZE];
- return mk_datestr (buffer, atime);
+ return mk_datestr (buffer, sizeof buffer, sig->timestamp);
}
const char *
expirestr_from_pk (PKT_public_key *pk)
{
- static char buffer[11+5];
- time_t atime;
+ static char buffer[MK_DATESTR_SIZE];
if (!pk->expiredate)
return _("never ");
- atime = pk->expiredate;
- return mk_datestr (buffer, atime);
+ return mk_datestr (buffer, sizeof buffer, pk->expiredate);
}
const char *
expirestr_from_sig (PKT_signature *sig)
{
- static char buffer[11+5];
- time_t atime;
+ static char buffer[MK_DATESTR_SIZE];
if (!sig->expiredate)
return _("never ");
- atime=sig->expiredate;
- return mk_datestr (buffer, atime);
+ return mk_datestr (buffer, sizeof buffer, sig->expiredate);
}
const char *
revokestr_from_pk( PKT_public_key *pk )
{
- static char buffer[11+5];
- time_t atime;
+ static char buffer[MK_DATESTR_SIZE];
if(!pk->revoked.date)
return _("never ");
- atime=pk->revoked.date;
- return mk_datestr (buffer, atime);
+ return mk_datestr (buffer, sizeof buffer, pk->revoked.date);
}
diff --git a/g10/keylist.c b/g10/keylist.c
index e2b8fef..86d1c56 100644
--- a/g10/keylist.c
+++ b/g10/keylist.c
@@ -44,6 +44,7 @@
#include "../common/mbox-util.h"
#include "../common/zb32.h"
#include "tofu.h"
+#include "../common/compliance.h"
static void list_all (ctrl_t, int, int);
@@ -192,7 +193,7 @@ print_seckey_info (ctrl_t ctrl, PKT_public_key *pk)
}
/* Print information about the public key. With FP passed as NULL,
- the tty output interface is used, otherwise output is directted to
+ the tty output interface is used, otherwise output is directed to
the given stream. */
void
print_pubkey_info (ctrl_t ctrl, estream_t fp, PKT_public_key *pk)
@@ -375,7 +376,7 @@ show_keyserver_url (PKT_signature * sig, int indent, int mode)
if (mode > 0)
log_info ("%s", str);
else
- tty_fprintf (es_stdout, "%s", str);
+ tty_fprintf (fp, "%s", str);
tty_print_utf8_string2 (fp, p, len, 0);
tty_fprintf (fp, "\n");
}
@@ -428,7 +429,7 @@ show_notation (PKT_signature * sig, int indent, int mode, int which)
if (mode > 0)
log_info ("%s", str);
else
- tty_fprintf (es_stdout, "%s", str);
+ tty_fprintf (fp, "%s", str);
/* This is all UTF8 */
tty_print_utf8_string2 (fp, nd->name, strlen (nd->name), 0);
tty_fprintf (fp, "=");
@@ -921,6 +922,21 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
if (opt.with_key_data)
print_key_data (pk);
+ if (opt.with_key_origin
+ && (pk->keyorg || pk->keyupdate || pk->updateurl))
+ {
+ char updatestr[MK_DATESTR_SIZE];
+
+ es_fprintf (es_stdout, " origin=%s last=%s %s",
+ key_origin_string (pk->keyorg),
+ mk_datestr (updatestr, sizeof updatestr, pk->keyupdate),
+ pk->updateurl? "url=":"");
+ if (pk->updateurl)
+ print_utf8_string (es_stdout, pk->updateurl);
+ es_putc ('\n', es_stdout);
+ }
+
+
for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
{
if (node->pkt->pkttype == PKT_USER_ID)
@@ -986,6 +1002,22 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
xfree (mbox);
}
+ if (opt.with_key_origin
+ && (uid->keyorg || uid->keyupdate || uid->updateurl))
+ {
+ char updatestr[MK_DATESTR_SIZE];
+
+ es_fprintf (es_stdout, " %*sorigin=%s last=%s %s",
+ indent, "",
+ key_origin_string (uid->keyorg),
+ mk_datestr (updatestr, sizeof updatestr,
+ uid->keyupdate),
+ uid->updateurl? "url=":"");
+ if (uid->updateurl)
+ print_utf8_string (es_stdout, uid->updateurl);
+ es_putc ('\n', es_stdout);
+ }
+
if ((opt.list_options & LIST_SHOW_PHOTOS) && uid->attribs != NULL)
show_photos (ctrl, uid->attribs, uid->numattribs, pk, uid);
}
@@ -1180,14 +1212,19 @@ print_compliance_flags (PKT_public_key *pk,
{
int any = 0;
+ if (!keylength)
+ keylength = nbits_from_pk (pk);
+
if (pk->version == 5)
{
- es_fputs ("8", es_stdout);
+ es_fputs (gnupg_status_compliance_flag (CO_GNUPG), es_stdout);
any++;
}
- if (gnupg_pk_is_compliant (CO_DE_VS, pk, keylength, curvename))
+ if (gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, pk->pkey,
+ keylength, curvename))
{
- es_fputs (any? " 23":"23", es_stdout);
+ es_fprintf (es_stdout, any ? " %s" : "%s",
+ gnupg_status_compliance_flag (CO_DE_VS));
any++;
}
}
@@ -1309,7 +1346,13 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
es_putc (':', es_stdout); /* End of field 17. */
print_compliance_flags (pk, keylength, curvename);
es_putc (':', es_stdout); /* End of field 18 (compliance). */
+ if (pk->keyupdate)
+ es_fputs (colon_strtime (pk->keyupdate), es_stdout);
es_putc (':', es_stdout); /* End of field 19 (last_update). */
+ es_fprintf (es_stdout, "%d%s", pk->keyorg, pk->updateurl? " ":"");
+ if (pk->updateurl)
+ es_write_sanitized (es_stdout, pk->updateurl, strlen (pk->updateurl),
+ ":", NULL);
es_putc (':', es_stdout); /* End of field 20 (origin). */
es_putc ('\n', es_stdout);
@@ -1361,7 +1404,14 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
else
es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
es_fputs (":::::::::", es_stdout);
+ if (uid->keyupdate)
+ es_fputs (colon_strtime (uid->keyupdate), es_stdout);
es_putc (':', es_stdout); /* End of field 19 (last_update). */
+ es_fprintf (es_stdout, "%d%s", uid->keyorg, uid->updateurl? " ":"");
+ if (uid->updateurl)
+ es_write_sanitized (es_stdout,
+ uid->updateurl, strlen (uid->updateurl),
+ ":", NULL);
es_putc (':', es_stdout); /* End of field 20 (origin). */
es_putc ('\n', es_stdout);
#ifdef USE_TOFU
diff --git a/g10/keyserver-internal.h b/g10/keyserver-internal.h
index 02452e8..46a1e1d 100644
--- a/g10/keyserver-internal.h
+++ b/g10/keyserver-internal.h
@@ -40,7 +40,7 @@ int keyserver_import_keyid (ctrl_t ctrl, u32 *keyid,
struct keyserver_spec *keyserver, int quick);
gpg_error_t 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_fetch (ctrl_t ctrl, strlist_t urilist, int origin);
int keyserver_import_cert (ctrl_t ctrl, const char *name, int dane_mode,
unsigned char **fpr,size_t *fpr_len);
gpg_error_t keyserver_import_pka (ctrl_t ctrl, const char *name,
diff --git a/g10/keyserver.c b/g10/keyserver.c
index c9be1f0..a8c222d 100644
--- a/g10/keyserver.c
+++ b/g10/keyserver.c
@@ -1590,11 +1590,12 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
{
gpg_error_t err = 0;
char **pattern;
- int idx, npat;
+ int idx, npat, npat_fpr;
estream_t datastream;
char *source = NULL;
size_t linelen; /* Estimated linelen for KS_GET. */
size_t n;
+ int only_fprs;
#define MAX_KS_GET_LINELEN 950 /* Somewhat lower than the real limit. */
@@ -1613,7 +1614,7 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
but we are sure that R_NDESC_USED has been updated. This avoids
a possible indefinite loop. */
linelen = 17; /* "KS_GET --quick --" */
- for (npat=idx=0; idx < ndesc; idx++)
+ for (npat=npat_fpr=0, idx=0; idx < ndesc; idx++)
{
int quiet = 0;
@@ -1635,6 +1636,8 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
desc[idx].mode == KEYDB_SEARCH_MODE_FPR20? 20 : 16,
pattern[npat]+2);
npat++;
+ if (desc[idx].mode == KEYDB_SEARCH_MODE_FPR20)
+ npat_fpr++;
}
}
else if(desc[idx].mode == KEYDB_SEARCH_MODE_LONG_KID)
@@ -1716,6 +1719,8 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
this is different from NPAT. */
*r_ndesc_used = idx;
+ only_fprs = (npat && npat == npat_fpr);
+
err = gpg_dirmngr_ks_get (ctrl, pattern, override_keyserver, quick,
&datastream, &source);
for (idx=0; idx < npat; idx++)
@@ -1746,7 +1751,9 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
r_fpr, r_fprlen,
(opt.keyserver_options.import_options
| IMPORT_NO_SECKEY),
- keyserver_retrieval_screener, &screenerarg);
+ keyserver_retrieval_screener, &screenerarg,
+ only_fprs? KEYORG_KS : 0,
+ source);
}
es_fclose (datastream);
xfree (source);
@@ -1852,7 +1859,7 @@ keyserver_put (ctrl_t ctrl, strlist_t keyspecs)
that the fetch operation ignores the configured keyservers and
instead directly retrieves the keys. */
int
-keyserver_fetch (ctrl_t ctrl, strlist_t urilist)
+keyserver_fetch (ctrl_t ctrl, strlist_t urilist, int origin)
{
gpg_error_t err;
strlist_t sl;
@@ -1877,7 +1884,7 @@ keyserver_fetch (ctrl_t ctrl, strlist_t urilist)
stats_handle = import_new_stats_handle();
import_keys_es_stream (ctrl, datastream, stats_handle, NULL, NULL,
opt.keyserver_options.import_options,
- NULL, NULL);
+ NULL, NULL, origin, sl->d);
import_print_stats (stats_handle);
import_release_stats_handle (stats_handle);
@@ -1925,14 +1932,36 @@ keyserver_import_cert (ctrl_t ctrl, const char *name, int dane_mode,
else if (key)
{
int armor_status=opt.no_armor;
+ import_filter_t save_filt;
/* CERTs and DANE records are always in binary format */
opt.no_armor=1;
-
- err = import_keys_es_stream (ctrl, key, NULL, fpr, fpr_len,
- (opt.keyserver_options.import_options
- | IMPORT_NO_SECKEY),
- NULL, NULL);
+ if (dane_mode)
+ {
+ save_filt = save_and_clear_import_filter ();
+ if (!save_filt)
+ err = gpg_error_from_syserror ();
+ else
+ {
+ char *filtstr = es_bsprintf ("keep-uid=mbox = %s", look);
+ err = filtstr? 0 : gpg_error_from_syserror ();
+ if (!err)
+ err = parse_and_set_import_filter (filtstr);
+ xfree (filtstr);
+ if (!err)
+ err = import_keys_es_stream (ctrl, key, NULL, fpr, fpr_len,
+ IMPORT_NO_SECKEY,
+ NULL, NULL, KEYORG_DANE, NULL);
+ restore_import_filter (save_filt);
+ }
+ }
+ else
+ {
+ err = import_keys_es_stream (ctrl, key, NULL, fpr, fpr_len,
+ (opt.keyserver_options.import_options
+ | IMPORT_NO_SECKEY),
+ NULL, NULL, 0, NULL);
+ }
opt.no_armor=armor_status;
@@ -2020,6 +2049,7 @@ keyserver_import_wkd (ctrl_t ctrl, const char *name, int quick,
gpg_error_t err;
char *mbox;
estream_t key;
+ char *url = NULL;
/* We want to work on the mbox. That is what dirmngr will do anyway
* and we need the mbox for the import filter anyway. */
@@ -2032,7 +2062,7 @@ keyserver_import_wkd (ctrl_t ctrl, const char *name, int quick,
return err;
}
- err = gpg_dirmngr_wkd_get (ctrl, mbox, quick, &key);
+ err = gpg_dirmngr_wkd_get (ctrl, mbox, quick, &key, &url);
if (err)
;
else if (key)
@@ -2055,7 +2085,7 @@ keyserver_import_wkd (ctrl_t ctrl, const char *name, int quick,
if (!err)
err = import_keys_es_stream (ctrl, key, NULL, fpr, fpr_len,
IMPORT_NO_SECKEY,
- NULL, NULL);
+ NULL, NULL, KEYORG_WKD, url);
}
@@ -2066,6 +2096,7 @@ keyserver_import_wkd (ctrl_t ctrl, const char *name, int quick,
key = NULL;
}
+ xfree (url);
xfree (mbox);
return err;
}
diff --git a/g10/main.h b/g10/main.h
index 129d746..87417ee 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -23,6 +23,7 @@
#include "../common/types.h"
#include "../common/iobuf.h"
#include "keydb.h"
+#include "keyedit.h"
#include "../common/util.h"
/* It could be argued that the default cipher should be 3DES rather
@@ -126,9 +127,6 @@ 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 (pubkey_algo_t algo);
-int gnupg_pk_is_compliant (int compliance, PKT_public_key *pk,
- unsigned int keylength, const char *curvename);
-
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);
@@ -158,7 +156,6 @@ int string_to_compress_algo(const char *string);
int check_compress_algo(int algo);
int default_cipher_algo(void);
int default_compress_algo(void);
-const char *compliance_option_string(void);
void compliance_failure(void);
struct parse_options
@@ -289,24 +286,6 @@ gpg_error_t check_signature_over_key_or_uid (ctrl_t ctrl,
gpg_error_t delete_keys (ctrl_t ctrl,
strlist_t names, int secret, int allow_both);
-/*-- keyedit.c --*/
-void keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
- strlist_t commands, int quiet, int seckey_check );
-void keyedit_passwd (ctrl_t ctrl, const char *username);
-void keyedit_quick_adduid (ctrl_t ctrl, const char *username,
- const char *newuid);
-void keyedit_quick_addkey (ctrl_t ctrl, const char *fpr, const char *algostr,
- const char *usagestr, const char *expirestr);
-void keyedit_quick_revuid (ctrl_t ctrl, const char *username,
- const char *uidtorev);
-void keyedit_quick_sign (ctrl_t ctrl, const char *fpr,
- strlist_t uids, strlist_t locusr, int local);
-void keyedit_quick_set_expire (ctrl_t ctrl,
- const char *fpr, const char *expirestr);
-void keyedit_quick_set_primary (ctrl_t ctrl, const char *username,
- const char *primaryuid);
-void show_basic_key_info (ctrl_t ctrl, kbnode_t keyblock);
-
/*-- keygen.c --*/
const char *get_default_pubkey_algo (void);
u32 parse_expire_string(const char *string);
@@ -373,15 +352,14 @@ void restore_import_filter (import_filter_t filt);
gpg_error_t read_key_from_file (ctrl_t ctrl, const char *fname,
kbnode_t *r_keyblock);
void import_keys (ctrl_t ctrl, char **fnames, int nnames,
- import_stats_t stats_hd, unsigned int options);
-int import_keys_stream (ctrl_t ctrl, iobuf_t inp, import_stats_t stats_hd,
- unsigned char **fpr,
- size_t *fpr_len, unsigned int options);
+ import_stats_t stats_hd, unsigned int options,
+ int origin, const char *url);
int import_keys_es_stream (ctrl_t ctrl, estream_t fp,
import_stats_t stats_handle,
unsigned char **fpr, size_t *fpr_len,
unsigned int options,
- import_screener_t screener, void *screener_arg);
+ import_screener_t screener, void *screener_arg,
+ int origin, const char *url);
gpg_error_t import_old_secring (ctrl_t ctrl, const char *fname);
import_stats_t import_new_stats_handle (void);
void import_release_stats_handle (import_stats_t hd);
diff --git a/g10/mainproc.c b/g10/mainproc.c
index 950f214..b712e60 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -39,6 +39,7 @@
#include "photoid.h"
#include "../common/mbox-util.h"
#include "call-dirmngr.h"
+#include "../common/compliance.h"
/* Put an upper limit on nested packets. The 32 is an arbitrary
value, a much lower should actually be sufficient. */
@@ -93,7 +94,7 @@ struct mainproc_context
kbnode_t list; /* The current list of packets. */
iobuf_t iobuf; /* Used to get the filename etc. */
int trustletter; /* Temporary usage in list_node. */
- ulong symkeys;
+ ulong symkeys; /* Number of symmetrically encrypted session keys. */
struct kidlist_item *pkenc_list; /* List of encryption packets. */
struct {
unsigned int sig_seen:1; /* Set to true if a signature packet
@@ -599,6 +600,46 @@ proc_encrypted (CTX c, PACKET *pkt)
else if (!c->dek)
result = GPG_ERR_NO_SECKEY;
+ /* Compute compliance with CO_DE_VS. */
+ if (!result && is_status_enabled ()
+ /* Symmetric encryption and asymmetric encryption voids compliance. */
+ && (c->symkeys != !!c->pkenc_list )
+ /* Overriding session key voids compliance. */
+ && !opt.override_session_key
+ /* Check symmetric cipher. */
+ && gnupg_cipher_is_compliant (CO_DE_VS, c->dek->algo,
+ GCRY_CIPHER_MODE_CFB))
+ {
+ struct kidlist_item *i;
+ int compliant = 1;
+ PKT_public_key *pk = xmalloc (sizeof *pk);
+
+ if ( !(c->pkenc_list || c->symkeys) )
+ log_debug ("%s: where else did the session key come from?\n", __func__);
+
+ /* Now check that every key used to encrypt the session key is
+ * compliant. */
+ for (i = c->pkenc_list; i && compliant; i = i->next)
+ {
+ memset (pk, 0, sizeof *pk);
+ pk->pubkey_algo = i->pubkey_algo;
+ if (get_pubkey (c->ctrl, pk, i->kid) != 0
+ || ! gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, pk->pkey,
+ nbits_from_pk (pk), NULL))
+ compliant = 0;
+ release_public_key_parts (pk);
+ }
+
+ xfree (pk);
+
+ if (compliant)
+ write_status_strings (STATUS_DECRYPTION_COMPLIANCE_MODE,
+ gnupg_status_compliance_flag (CO_DE_VS),
+ NULL);
+
+ }
+
+
if (!result)
result = decrypt_data (c->ctrl, c, pkt->pkt.encrypted, c->dek );
@@ -640,7 +681,8 @@ proc_encrypted (CTX c, PACKET *pkt)
}
else
{
- if (gpg_err_code (result) == GPG_ERR_BAD_KEY
+ if ((gpg_err_code (result) == GPG_ERR_BAD_KEY
+ || gpg_err_code (result) == GPG_ERR_CIPHER_ALGO)
&& *c->dek->s2k_cacheid != '\0')
{
if (opt.debug)
@@ -845,7 +887,7 @@ proc_compressed (CTX c, PACKET *pkt)
/*
* Check the signature. If R_PK is not NULL a copy of the public key
- * used to verify the signature will be stored tehre, or NULL if not
+ * used to verify the signature will be stored there, or NULL if not
* found. Returns: 0 = valid signature or an error code
*/
static int
@@ -1617,6 +1659,7 @@ check_sig_and_print (CTX c, kbnode_t node)
int is_revkey = 0;
char *issuer_fpr;
PKT_public_key *pk = NULL; /* The public key for the signature or NULL. */
+ int tried_ks_by_fpr;
if (opt.skip_verify)
{
@@ -1845,6 +1888,7 @@ check_sig_and_print (CTX c, kbnode_t node)
* that the signers fingerprint is encoded in the signature. We
* favor this over the WKD method (to be tried next), because an
* arbitrary keyserver is less subject to web bug like monitoring. */
+ tried_ks_by_fpr = 0;
if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
&& (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE)
&& keyserver_any_configured (c->ctrl))
@@ -1861,6 +1905,7 @@ check_sig_and_print (CTX c, kbnode_t node)
pk = NULL;
glo_ctrl.in_auto_key_retrieve++;
res = keyserver_import_fprint (c->ctrl, p+1, n-1, opt.keyserver, 1);
+ tried_ks_by_fpr = 1;
glo_ctrl.in_auto_key_retrieve--;
if (!res)
rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey, &pk);
@@ -1892,6 +1937,7 @@ check_sig_and_print (CTX c, kbnode_t node)
* keyserver. */
if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
&& (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE)
+ && !tried_ks_by_fpr
&& keyserver_any_configured (c->ctrl))
{
int res;
@@ -1925,7 +1971,7 @@ check_sig_and_print (CTX c, kbnode_t node)
statno = STATUS_GOODSIG;
/* FIXME: We should have the public key in PK and thus the
- * keyboock has already been fetched. Thus we could use the
+ * keyblock has already been fetched. Thus we could use the
* fingerprint or PK itself to lookup the entire keyblock. That
* would best be done with a cache. */
keyblock = get_pubkeyblock (c->ctrl, sig->keyid);
@@ -2122,6 +2168,16 @@ check_sig_and_print (CTX c, kbnode_t node)
mainpkhex);
}
+ /* Print compliance warning for Good signatures. */
+ if (!rc && pk && !opt.quiet
+ && !gnupg_pk_is_compliant (opt.compliance, pk->pubkey_algo,
+ pk->pkey, nbits_from_pk (pk), NULL))
+ {
+ log_info (_("WARNING: This key is not suitable for signing"
+ " in %s mode\n"),
+ gnupg_compliance_option_string (opt.compliance));
+ }
+
/* For good signatures compute and print the trust information.
Note that in the Tofu trust model this may ask the user on
how to resolve a conflict. */
@@ -2196,6 +2252,15 @@ check_sig_and_print (CTX c, kbnode_t node)
}
}
+ /* Compute compliance with CO_DE_VS. */
+ if (pk && is_status_enabled ()
+ && gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, pk->pkey,
+ nbits_from_pk (pk), NULL)
+ && gnupg_digest_is_compliant (CO_DE_VS, sig->digest_algo))
+ write_status_strings (STATUS_VERIFICATION_COMPLIANCE_MODE,
+ gnupg_status_compliance_flag (CO_DE_VS),
+ NULL);
+
free_public_key (pk);
pk = NULL;
release_kbnode( keyblock );
diff --git a/g10/misc.c b/g10/misc.c
index abae6c9..77c8f26 100644
--- a/g10/misc.c
+++ b/g10/misc.c
@@ -707,94 +707,6 @@ openpgp_pk_algo_name (pubkey_algo_t algo)
}
-/* Return true if PK is compliant to the give COMPLIANCE mode. If
- * KEYLENGTH and CURVENAME are not 0/NULL the are assumed to be the
- * already computed values from PK. */
-int
-gnupg_pk_is_compliant (int compliance, PKT_public_key *pk,
- unsigned int keylength, const char *curvename)
-{
- enum { is_rsa, is_pgp5, is_elg_sign, is_ecc } algotype;
- int result;
-
- switch (pk->pubkey_algo)
- {
- case PUBKEY_ALGO_RSA:
- case PUBKEY_ALGO_RSA_E:
- case PUBKEY_ALGO_RSA_S:
- algotype = is_rsa;
- break;
-
- case PUBKEY_ALGO_ELGAMAL_E:
- case PUBKEY_ALGO_DSA:
- algotype = is_pgp5;
- break;
-
- case PUBKEY_ALGO_ECDH:
- case PUBKEY_ALGO_ECDSA:
- case PUBKEY_ALGO_EDDSA:
- algotype = is_ecc;
- break;
-
- case PUBKEY_ALGO_ELGAMAL:
- algotype = is_elg_sign;
- break;
-
- default: /* Unknown. */
- return 0;
- }
-
- if (compliance == CO_DE_VS)
- {
- char *curve = NULL;
-
- switch (algotype)
- {
- case is_pgp5:
- result = 0;
- break;
-
- case is_rsa:
- if (!keylength)
- keylength = nbits_from_pk (pk);
- result = (keylength >= 2048);
- break;
-
- case is_ecc:
- if (!curvename)
- {
- curve = openpgp_oid_to_str (pk->pkey[0]);
- curvename = openpgp_oid_to_curve (curve, 0);
- if (!curvename)
- curvename = curve;
- }
-
- result = (curvename
- && pk->pubkey_algo != PUBKEY_ALGO_EDDSA
- && (!strcmp (curvename, "brainpoolP256r1")
- || !strcmp (curvename, "brainpoolP384r1")
- || !strcmp (curvename, "brainpoolP512r1")));
- break;
-
- default:
- result = 0;
- }
- xfree (curve);
- }
- else if (algotype == is_elg_sign)
- {
- /* An Elgamal signing key is only RFC-2440 compliant. */
- result = (compliance == RFC2440);
- }
- else
- {
- result = 1; /* Assume compliance. */
- }
-
- return result;
-}
-
-
/* Explicit mapping of OpenPGP digest algos to Libgcrypt. */
/* FIXME: We do not yes use it everywhere. */
enum gcry_md_algos
@@ -1330,24 +1242,6 @@ default_compress_algo(void)
return DEFAULT_COMPRESS_ALGO;
}
-const char *
-compliance_option_string(void)
-{
- char *ver="???";
-
- switch(opt.compliance)
- {
- case CO_GNUPG: return "--gnupg";
- case CO_RFC4880: return "--openpgp";
- case CO_RFC2440: return "--rfc2440";
- case CO_PGP6: return "--pgp6";
- case CO_PGP7: return "--pgp7";
- case CO_PGP8: return "--pgp8";
- case CO_DE_VS: return "--compliance=de-vs";
- }
-
- return ver;
-}
void
compliance_failure(void)
diff --git a/g10/options.h b/g10/options.h
index c634f0f..83f4028 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -28,6 +28,7 @@
#include "packet.h"
#include "tofu.h"
#include "../common/session-env.h"
+#include "../common/compliance.h"
#ifndef EXTERN_UNLESS_MAIN_MODULE
/* Norcraft can't cope with common symbols */
@@ -84,6 +85,7 @@ struct
int with_tofu_info; /* Option --with-tofu_info active. */
int with_secret; /* Option --with-secret active. */
int with_wkd_hash; /* Option --with-wkd-hash. */
+ int with_key_origin; /* Option --with-key-origin. */
int fingerprint; /* list fingerprints */
int list_sigs; /* list signatures */
int no_armor;
@@ -139,11 +141,7 @@ struct
} trust_model;
enum tofu_policy tofu_default_policy;
int force_ownertrust;
- enum
- {
- CO_GNUPG, CO_RFC4880, CO_RFC2440,
- CO_PGP6, CO_PGP7, CO_PGP8, CO_DE_VS
- } compliance;
+ enum gnupg_compliance_mode compliance;
enum
{
KF_DEFAULT, KF_NONE, KF_SHORT, KF_LONG, KF_0xSHORT, KF_0xLONG
@@ -266,6 +264,10 @@ struct
struct akl *next;
} *auto_key_locate;
+ /* The value of --key-origin. See parse_key_origin(). */
+ int key_origin;
+ char *key_origin_url;
+
int passphrase_repeat;
int pinentry_mode;
@@ -349,6 +351,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode;
#define IMPORT_KEEP_OWNERTTRUST (1<<8)
#define IMPORT_EXPORT (1<<9)
#define IMPORT_RESTORE (1<<10)
+#define IMPORT_REPAIR_KEYS (1<<11)
#define EXPORT_LOCAL_SIGS (1<<0)
#define EXPORT_ATTRIBUTES (1<<1)
diff --git a/g10/packet.h b/g10/packet.h
index cf2121c..8dca88b 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -285,7 +285,7 @@ typedef struct
u32 created; /* according to the self-signature */
u32 keyupdate; /* From the ring trust packet. */
char *updateurl; /* NULL or the URL of the last update origin. */
- byte keysrc; /* From the ring trust packet. */
+ byte keyorg; /* From the ring trust packet. */
byte selfsigversion;
struct
{
@@ -407,7 +407,7 @@ typedef struct
u32 trust_timestamp;
byte trust_depth;
byte trust_value;
- byte keysrc; /* From the ring trust packet. */
+ byte keyorg; /* From the ring trust packet. */
u32 keyupdate; /* From the ring trust packet. */
char *updateurl; /* NULL or the URL of the last update origin. */
const byte *trust_regexp;
@@ -485,8 +485,8 @@ typedef struct {
/* Subtypes for the ring trust packet. */
#define RING_TRUST_SIG 0 /* The classical signature cache. */
-#define RING_TRUST_KEY 1 /* A KEYSRC on a primary key. */
-#define RING_TRUST_UID 2 /* A KEYSRC on a user id. */
+#define RING_TRUST_KEY 1 /* A KEYORG on a primary key. */
+#define RING_TRUST_UID 2 /* A KEYORG on a user id. */
/* The local only ring trust packet which OpenPGP declares as
* implementation defined. GnuPG uses this to cache signature
@@ -498,7 +498,7 @@ typedef struct {
unsigned int trustval;
unsigned int sigcache;
unsigned char subtype; /* The subtype of this ring trust packet. */
- unsigned char keysrc; /* The origin of the key (KEYSRC_*). */
+ unsigned char keyorg; /* The origin of the key (KEYORG_*). */
u32 keyupdate; /* The wall time the key was last updated. */
char *url; /* NULL or the URL of the source. */
} PKT_ring_trust;
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index dbb7af8..0b6ee8b 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -2942,7 +2942,7 @@ parse_ring_trust (parse_packet_ctx_t ctx, unsigned long pktlen)
int i;
unsigned int namelen;
- rt.keysrc = iobuf_get_noeof (inp);
+ rt.keyorg = iobuf_get_noeof (inp);
pktlen--;
rt.keyupdate = read_32 (inp);
pktlen -= 4;
@@ -2974,7 +2974,7 @@ parse_ring_trust (parse_packet_ctx_t ctx, unsigned long pktlen)
es_fprintf (listfp, ":trust packet: %s upd=%lu src=%d%s",
(rt.subtype == RING_TRUST_UID? "uid" : "key"),
(unsigned long)rt.keyupdate,
- rt.keysrc,
+ rt.keyorg,
(rt.url? " url=":""));
if (rt.url)
{
@@ -3016,7 +3016,7 @@ parse_ring_trust (parse_packet_ctx_t ctx, unsigned long pktlen)
{
PKT_user_id *uid = ctx->last_pkt.pkt.user_id;
- uid->keysrc = rt.keysrc;
+ uid->keyorg = rt.keyorg;
uid->keyupdate = rt.keyupdate;
uid->updateurl = rt.url;
rt.url = NULL;
@@ -3027,7 +3027,7 @@ parse_ring_trust (parse_packet_ctx_t ctx, unsigned long pktlen)
{
PKT_public_key *pk = ctx->last_pkt.pkt.public_key;
- pk->keysrc = rt.keysrc;
+ pk->keyorg = rt.keyorg;
pk->keyupdate = rt.keyupdate;
pk->updateurl = rt.url;
rt.url = NULL;
diff --git a/g10/pkclist.c b/g10/pkclist.c
index ab024d9..67d932e 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -1026,9 +1026,9 @@ build_pk_list (ctrl_t ctrl, strlist_t rcpts, PK_LIST *ret_pk_list)
issue a warning and switch into GnuPG mode. */
if ((rov->flags & PK_LIST_HIDDEN) && (PGP6 || PGP7 || PGP8))
{
- log_info(_("you may not use %s while in %s mode\n"),
+ log_info(_("option '%s' may not be used in %s mode\n"),
"--hidden-recipient",
- compliance_option_string());
+ gnupg_compliance_option_string (opt.compliance));
compliance_failure();
}
@@ -1077,9 +1077,9 @@ build_pk_list (ctrl_t ctrl, strlist_t rcpts, PK_LIST *ret_pk_list)
GnuPG mode. */
if ((r->flags&PK_LIST_ENCRYPT_TO) && (PGP6 || PGP7 || PGP8))
{
- log_info(_("you may not use %s while in %s mode\n"),
+ log_info(_("option '%s' may not be used in %s mode\n"),
"--hidden-encrypt-to",
- compliance_option_string());
+ gnupg_compliance_option_string (opt.compliance));
compliance_failure();
}
diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c
index d0eaab7..272562b 100644
--- a/g10/pubkey-enc.c
+++ b/g10/pubkey-enc.c
@@ -35,6 +35,7 @@
#include "pkglue.h"
#include "call-agent.h"
#include "../common/host2net.h"
+#include "../common/compliance.h"
static gpg_error_t get_it (ctrl_t ctrl, PKT_pubkey_enc *k,
@@ -88,7 +89,18 @@ get_session_key (ctrl_t ctrl, PKT_pubkey_enc * k, DEK * dek)
sk = xmalloc_clear (sizeof *sk);
sk->pubkey_algo = k->pubkey_algo; /* We want a pubkey with this algo. */
if (!(rc = get_seckey (ctrl, sk, k->keyid)))
- rc = get_it (ctrl, k, dek, sk, k->keyid);
+ {
+ /* Print compliance warning. */
+ if (!gnupg_pk_is_compliant (opt.compliance,
+ sk->pubkey_algo,
+ sk->pkey, nbits_from_pk (sk), NULL))
+ log_info (_("Note: key %s is not suitable for encryption"
+ " in %s mode\n"),
+ keystr_from_pk (sk),
+ gnupg_compliance_option_string (opt.compliance));
+
+ rc = get_it (ctrl, k, dek, sk, k->keyid);
+ }
}
else if (opt.skip_hidden_recipients)
rc = gpg_error (GPG_ERR_NO_SECKEY);
@@ -116,6 +128,15 @@ get_session_key (ctrl_t ctrl, PKT_pubkey_enc * k, DEK * dek)
log_info (_("anonymous recipient; trying secret key %s ...\n"),
keystr (keyid));
+ /* Print compliance warning. */
+ if (!gnupg_pk_is_compliant (opt.compliance,
+ sk->pubkey_algo,
+ sk->pkey, nbits_from_pk (sk), NULL))
+ log_info (_("Note: key %s is not suitable for encryption"
+ " in %s mode\n"),
+ keystr_from_pk (sk),
+ gnupg_compliance_option_string (opt.compliance));
+
rc = get_it (ctrl, k, dek, sk, keyid);
if (!rc)
{
@@ -129,7 +150,7 @@ get_session_key (ctrl_t ctrl, PKT_pubkey_enc * k, DEK * dek)
enum_secret_keys (ctrl, &enum_context, NULL); /* free context */
}
-leave:
+ leave:
free_public_key (sk);
if (DBG_CLOCK)
log_clock ("get_session_key leave");
diff --git a/g10/sig-check.c b/g10/sig-check.c
index 19906e2..60e988e 100644
--- a/g10/sig-check.c
+++ b/g10/sig-check.c
@@ -33,6 +33,7 @@
#include "../common/i18n.h"
#include "options.h"
#include "pkglue.h"
+#include "../common/compliance.h"
static int check_signature_end (PKT_public_key *pk, PKT_signature *sig,
gcry_md_hd_t digest,
@@ -132,6 +133,14 @@ check_signature2 (ctrl_t ctrl,
if ( (rc=openpgp_md_test_algo(sig->digest_algo)) )
; /* We don't have this digest. */
+ else if (! gnupg_digest_is_allowed (opt.compliance, 0, sig->digest_algo))
+ {
+ /* Compliance failure. */
+ log_info (_("digest algorithm '%s' may not be used in %s mode\n"),
+ gcry_md_algo_name (sig->digest_algo),
+ gnupg_compliance_option_string (opt.compliance));
+ rc = gpg_error (GPG_ERR_DIGEST_ALGO);
+ }
else if ((rc=openpgp_pk_test_algo(sig->pubkey_algo)))
; /* We don't have this pubkey algo. */
else if (!gcry_md_is_enabled (digest,sig->digest_algo))
@@ -146,6 +155,17 @@ check_signature2 (ctrl_t ctrl,
}
else if( get_pubkey (ctrl, pk, sig->keyid ) )
rc = gpg_error (GPG_ERR_NO_PUBKEY);
+ else if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_VERIFICATION,
+ pk->pubkey_algo, pk->pkey,
+ nbits_from_pk (pk),
+ NULL))
+ {
+ /* Compliance failure. */
+ log_error (_("key %s may not be used for signing in %s mode\n"),
+ keystr_from_pk (pk),
+ gnupg_compliance_option_string (opt.compliance));
+ rc = gpg_error (GPG_ERR_PUBKEY_ALGO);
+ }
else if(!pk->flags.valid)
{
/* You cannot have a good sig from an invalid key. */
@@ -185,6 +205,7 @@ check_signature2 (ctrl_t ctrl,
rc = gpg_error (GPG_ERR_GENERAL);
}
}
+
}
if( !rc && sig->sig_class < 2 && is_status_enabled() ) {
diff --git a/g10/sign.c b/g10/sign.c
index af1a7b6..4cf0cd3 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -41,6 +41,7 @@
#include "../common/sysutils.h"
#include "call-agent.h"
#include "../common/mbox-util.h"
+#include "../common/compliance.h"
#ifdef HAVE_DOSISH_SYSTEM
#define LF "\r\n"
@@ -251,7 +252,7 @@ hash_sigversion_to_magic (gcry_md_hd_t md, const PKT_signature *sig)
/* Perform the sign operation. If CACHE_NONCE is given the agent is
- advised to use that cached passphrase fro the key. */
+ advised to use that cached passphrase for the key. */
static int
do_sign (ctrl_t ctrl, PKT_public_key *pksk, PKT_signature *sig,
gcry_md_hd_t md, int mdalgo, const char *cache_nonce)
@@ -277,6 +278,36 @@ do_sign (ctrl_t ctrl, PKT_public_key *pksk, PKT_signature *sig,
if (!mdalgo)
mdalgo = gcry_md_get_algo (md);
+ /* Check compliance. */
+ if (! gnupg_digest_is_allowed (opt.compliance, 1, mdalgo))
+ {
+ log_error (_("digest algorithm '%s' may not be used in %s mode\n"),
+ gcry_md_algo_name (mdalgo),
+ gnupg_compliance_option_string (opt.compliance));
+ err = gpg_error (GPG_ERR_DIGEST_ALGO);
+ goto leave;
+ }
+
+ if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_SIGNING, pksk->pubkey_algo,
+ pksk->pkey, nbits_from_pk (pksk), NULL))
+ {
+ log_error (_("key %s may not be used for signing in %s mode\n"),
+ keystr_from_pk (pksk),
+ gnupg_compliance_option_string (opt.compliance));
+ err = gpg_error (GPG_ERR_PUBKEY_ALGO);
+ goto leave;
+ }
+
+ if (!gnupg_rng_is_compliant (opt.compliance))
+ {
+ err = gpg_error (GPG_ERR_FORBIDDEN);
+ log_error (_("%s is not compliant with %s mode\n"),
+ "RNG",
+ gnupg_compliance_option_string (opt.compliance));
+ write_status_error ("random-compliance", err);
+ goto leave;
+ }
+
print_digest_algo_note (mdalgo);
dp = gcry_md_read (md, mdalgo);
sig->digest_algo = mdalgo;
@@ -321,6 +352,7 @@ do_sign (ctrl_t ctrl, PKT_public_key *pksk, PKT_signature *sig,
}
xfree (hexgrip);
+ leave:
if (err)
log_error (_("signing failed: %s\n"), gpg_strerror (err));
else
diff --git a/g10/skclist.c b/g10/skclist.c
index 489277c..78890dc 100644
--- a/g10/skclist.c
+++ b/g10/skclist.c
@@ -137,7 +137,7 @@ build_sk_list (ctrl_t ctrl,
pk = xmalloc_clear (sizeof *pk);
pk->req_usage = use;
- /* Check if a card is available. If any, use it. */
+ /* Check if a card is available. If any, use the key as a hint. */
err = agent_scd_serialno (&serialno, NULL);
if (!err)
{
@@ -146,19 +146,11 @@ build_sk_list (ctrl_t ctrl,
if (err)
log_error ("error retrieving key fingerprint from card: %s\n",
gpg_strerror (err));
- else if (info.fpr1valid)
- {
- if ((err = get_pubkey_byfprint (ctrl, pk, NULL, info.fpr1, 20)))
- {
- info.fpr1valid = 0;
- log_error ("error on card key to sign: %s, try default\n",
- gpg_strerror (err));
- }
- }
}
- if (!info.fpr1valid
- && (err = getkey_byname (ctrl, NULL, pk, NULL, 1, NULL)))
+ err = get_seckey_default_or_card (ctrl, pk,
+ info.fpr1valid? info.fpr1 : NULL, 20);
+ if (err)
{
free_public_key (pk);
pk = NULL;
diff --git a/g10/sqrtu32.c b/g10/sqrtu32.c
deleted file mode 100644
index 1490b31..0000000
--- a/g10/sqrtu32.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/* sqrtu32.c - Return the very approximate sqrt of an unsigned integer.
- *
- * This file by g10 Code GmbH
- *
- * To the extent possible under law, the person who associated CC0 with
- * g10 Code GmbH has waived all copyright and related or neighboring rights
- * to this file.
- *
- * You should have received a copy of the CC0 legalcode along with this
- * work. If not, see <https://creativecommons.org/publicdomain/zero/1.0/>.
- */
-
-/* The R code to generate the following table. */
-#if 0
-{
- m = 2^32 - 1
- last.i = 0
- last.sqrt = 0
- i = 0
- while (i < m) {
- if (sqrt(i) - last.sqrt > 0.05 * last.sqrt) {
- cat(paste0(" if (i <= ", last.i, "u) return ", last.sqrt, ";\n"));
- last.i = i
- last.sqrt = sqrt(i)
- }
- i = i + max(1, floor(last.sqrt / 10))
- }
- cat(paste0(" return ", sqrt(m), ";\n"))
-}
-#endif
-
-float
-sqrtu32 (unsigned int i)
-{
- if (i <= 0u) return 0;
- if (i <= 1u) return 1;
- if (i <= 2u) return 1.4142135623731;
- if (i <= 3u) return 1.73205080756888;
- if (i <= 4u) return 2;
- if (i <= 5u) return 2.23606797749979;
- if (i <= 6u) return 2.44948974278318;
- if (i <= 7u) return 2.64575131106459;
- if (i <= 8u) return 2.82842712474619;
- if (i <= 9u) return 3;
- if (i <= 10u) return 3.16227766016838;
- if (i <= 12u) return 3.46410161513775;
- if (i <= 14u) return 3.74165738677394;
- if (i <= 16u) return 4;
- if (i <= 18u) return 4.24264068711928;
- if (i <= 20u) return 4.47213595499958;
- if (i <= 23u) return 4.79583152331272;
- if (i <= 26u) return 5.09901951359278;
- if (i <= 29u) return 5.3851648071345;
- if (i <= 32u) return 5.65685424949238;
- if (i <= 36u) return 6;
- if (i <= 40u) return 6.32455532033676;
- if (i <= 45u) return 6.70820393249937;
- if (i <= 50u) return 7.07106781186548;
- if (i <= 56u) return 7.48331477354788;
- if (i <= 62u) return 7.87400787401181;
- if (i <= 69u) return 8.30662386291807;
- if (i <= 77u) return 8.77496438739212;
- if (i <= 85u) return 9.21954445729289;
- if (i <= 94u) return 9.69535971483266;
- if (i <= 104u) return 10.1980390271856;
- if (i <= 115u) return 10.7238052947636;
- if (i <= 127u) return 11.2694276695846;
- if (i <= 141u) return 11.8743420870379;
- if (i <= 156u) return 12.4899959967968;
- if (i <= 172u) return 13.114877048604;
- if (i <= 190u) return 13.7840487520902;
- if (i <= 210u) return 14.4913767461894;
- if (i <= 232u) return 15.2315462117278;
- if (i <= 256u) return 16;
- if (i <= 283u) return 16.8226038412607;
- if (i <= 313u) return 17.6918060129541;
- if (i <= 346u) return 18.6010752377383;
- if (i <= 382u) return 19.5448202856921;
- if (i <= 422u) return 20.5426385841741;
- if (i <= 466u) return 21.5870331449229;
- if (i <= 514u) return 22.6715680975093;
- if (i <= 568u) return 23.832750575626;
- if (i <= 628u) return 25.0599281722833;
- if (i <= 694u) return 26.343879744639;
- if (i <= 766u) return 27.6767050061961;
- if (i <= 846u) return 29.086079144498;
- if (i <= 934u) return 30.5614135798723;
- if (i <= 1030u) return 32.0936130717624;
- if (i <= 1138u) return 33.734255586866;
- if (i <= 1255u) return 35.4259791678367;
- if (i <= 1384u) return 37.2021504754766;
- if (i <= 1528u) return 39.0896405713841;
- if (i <= 1687u) return 41.0731055558257;
- if (i <= 1863u) return 43.1624837098145;
- if (i <= 2055u) return 45.3321078265725;
- if (i <= 2267u) return 47.6130234284697;
- if (i <= 2503u) return 50.029991005396;
- if (i <= 2763u) return 52.5642464038057;
- if (i <= 3048u) return 55.208694967369;
- if (i <= 3363u) return 57.9913786695919;
- if (i <= 3708u) return 60.8933493905533;
- if (i <= 4092u) return 63.9687423668779;
- if (i <= 4512u) return 67.1714224949867;
- if (i <= 4980u) return 70.5691150575094;
- if (i <= 5491u) return 74.1012820401914;
- if (i <= 6058u) return 77.8331548891602;
- if (i <= 6681u) return 81.7373843476778;
- if (i <= 7369u) return 85.842879728024;
- if (i <= 8129u) return 90.160967164289;
- if (i <= 8966u) return 94.6889645101265;
- if (i <= 9893u) return 99.4635611668917;
- if (i <= 10910u) return 104.450945424156;
- if (i <= 12030u) return 109.68135666557;
- if (i <= 13270u) return 115.195486022674;
- if (i <= 14634u) return 120.971070921936;
- if (i <= 16134u) return 127.019683514013;
- if (i <= 17790u) return 133.379158791769;
- if (i <= 19623u) return 140.08211877324;
- if (i <= 21639u) return 147.102005424807;
- if (i <= 23865u) return 154.483008774428;
- if (i <= 26325u) return 162.24980739588;
- if (i <= 29029u) return 170.378989314997;
- if (i <= 32021u) return 178.94412535761;
- if (i <= 35319u) return 187.933498876597;
- if (i <= 38955u) return 197.370210518204;
- if (i <= 42964u) return 207.277591649459;
- if (i <= 47384u) return 217.678662252413;
- if (i <= 52256u) return 228.595712995673;
- if (i <= 57624u) return 240.049994792751;
- if (i <= 63552u) return 252.09522010542;
- if (i <= 70077u) return 264.720607433573;
- if (i <= 77279u) return 277.991007048789;
- if (i <= 85217u) return 291.919509454233;
- if (i <= 93975u) return 306.553421119387;
- if (i <= 103635u) return 321.923904051874;
- if (i <= 114259u) return 338.022188620806;
- if (i <= 125974u) return 354.928161745444;
- if (i <= 138889u) return 372.678145321134;
- if (i <= 153134u) return 391.323395671662;
- if (i <= 168851u) return 410.914833025044;
- if (i <= 186194u) return 431.5020278052;
- if (i <= 205286u) return 453.084980991425;
- if (i <= 226346u) return 475.758342018298;
- if (i <= 249564u) return 499.563809738055;
- if (i <= 275191u) return 524.586503829445;
- if (i <= 303427u) return 550.842082633489;
- if (i <= 334557u) return 578.409024825858;
- if (i <= 368871u) return 607.347511726195;
- if (i <= 406731u) return 637.754655020251;
- if (i <= 448437u) return 669.654388472143;
- if (i <= 494439u) return 703.163565609027;
- if (i <= 545119u) return 738.321745582507;
- if (i <= 601037u) return 775.265760884614;
- if (i <= 662714u) return 814.072478345755;
- if (i <= 730673u) return 854.794127261062;
- if (i <= 805643u) return 897.576180610872;
- if (i <= 888235u) return 942.46220083354;
- if (i <= 979321u) return 989.60648744842;
- if (i <= 1079771u) return 1039.1203010239;
- if (i <= 1190496u) return 1091.09852900643;
- if (i <= 1312576u) return 1145.67709237813;
- if (i <= 1447210u) return 1203.00041562753;
- if (i <= 1595650u) return 1263.19040528338;
- if (i <= 1759324u) return 1326.3951145869;
- if (i <= 1939768u) return 1392.75554208195;
- if (i <= 2138677u) return 1462.42162183141;
- if (i <= 2357969u) return 1535.5679730966;
- if (i <= 2599709u) return 1612.3613118653;
- if (i <= 2866325u) return 1693.02244521448;
- if (i <= 3160216u) return 1777.69963717159;
- if (i <= 3484303u) return 1866.62877937741;
- if (i <= 3841609u) return 1960.00229591702;
- if (i <= 4235569u) return 2058.04980503388;
- if (i <= 4669759u) return 2160.962517028;
- if (i <= 5148415u) return 2269.011899484;
- if (i <= 5676351u) return 2382.50939137708;
- if (i <= 6258261u) return 2501.65165440754;
- if (i <= 6899761u) return 2626.73961404628;
- if (i <= 7607161u) return 2758.10822847835;
- if (i <= 8387061u) return 2896.04229941484;
- if (i <= 9246836u) return 3040.86106226509;
- if (i <= 10194708u) return 3192.91528230863;
- if (i <= 11239752u) return 3352.57393654487;
- if (i <= 12392152u) return 3520.24885483967;
- if (i <= 13662520u) return 3696.2846210756;
- if (i <= 15063244u) return 3881.13952338743;
- if (i <= 16607484u) return 4075.22809177597;
- if (i <= 18309965u) return 4279.01448934214;
- if (i <= 20187057u) return 4493.00089027367;
- if (i <= 22256498u) return 4717.67930236891;
- if (i <= 24538022u) return 4953.58678131311;
- if (i <= 27053612u) return 5201.30868147623;
- if (i <= 29826772u) return 5461.3892005606;
- if (i <= 32884372u) return 5734.48968958878;
- if (i <= 36255331u) return 6021.23998857378;
- if (i <= 39972079u) return 6322.34758614235;
- if (i <= 44069335u) return 6638.47384569677;
- if (i <= 48587017u) return 6970.43879537006;
- if (i <= 53567779u) return 7319.00122967608;
- if (i <= 59059051u) return 7684.98867923694;
- if (i <= 65113195u) return 8069.27475055844;
- if (i <= 71787681u) return 8472.76112020161;
- if (i <= 79146417u) return 8896.4272042208;
- if (i <= 87259431u) return 9341.27566234934;
- if (i <= 96204349u) return 9808.38156884203;
- if (i <= 106066089u) return 10298.8392064349;
- if (i <= 116938503u) return 10813.8107529215;
- if (i <= 128925712u) return 11354.5458737899;
- if (i <= 142141652u) return 11922.3173921851;
- if (i <= 156711468u) return 12518.445111115;
- if (i <= 172775559u) return 13144.4117023167;
- if (i <= 190485651u) return 13801.6539226283;
- if (i <= 210011271u) return 14491.7656274175;
- if (i <= 231537615u) return 15216.360110092;
- if (i <= 255271299u) return 15977.2118656542;
- if (i <= 281438144u) return 16776.1182637701;
- if (i <= 310285898u) return 17614.9339482156;
- if (i <= 342091319u) return 18495.710827108;
- if (i <= 377155755u) return 19420.4983200741;
- if (i <= 415815149u) return 20391.5460178967;
- if (i <= 458436366u) return 21411.1271538889;
- if (i <= 505427034u) return 22481.7044282679;
- if (i <= 557234442u) return 23605.8137330616;
- if (i <= 614351162u) return 24786.1082463544;
- if (i <= 677324576u) return 26025.4601496304;
- if (i <= 746751140u) return 27326.7477025716;
- if (i <= 823293584u) return 28693.0929667751;
- if (i <= 907682350u) return 30127.7670928331;
- if (i <= 1000720018u) return 31634.1590373444;
- if (i <= 1103296108u) return 33215.9014328981;
- if (i <= 1216386121u) return 34876.7274984337;
- if (i <= 1341067293u) return 36620.5856452351;
- if (i <= 1478527787u) return 38451.6291852504;
- if (i <= 1630078462u) return 40374.2301722274;
- if (i <= 1797161818u) return 42392.9453800983;
- if (i <= 1981371802u) return 44512.60273226;
- if (i <= 2184466481u) return 46738.2764016817;
- if (i <= 2408377949u) return 49075.2274472569;
- if (i <= 2655239305u) return 51529.014205591;
- if (i <= 2927404009u) return 54105.4896382983;
- if (i <= 3227464249u) return 56810.7758176211;
- if (i <= 3558280241u) return 59651.3222066368;
- return 65535.9999923706;
-}
diff --git a/g10/sqrtu32.h b/g10/sqrtu32.h
deleted file mode 100644
index 566784d..0000000
--- a/g10/sqrtu32.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* sqrtu32.h - Return the very approximate sqrt of an unsigned integer.
- *
- * This file by g10 Code GmbH
- *
- * To the extent possible under law, the person who associated CC0 with
- * g10 Code GmbH has waived all copyright and related or neighboring rights
- * to this file.
- *
- * You should have received a copy of the CC0 legalcode along with this
- * work. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
- */
-
-/* Return the very approximate square root of an unsigned integer. */
-float sqrtu32 (unsigned int i);
diff --git a/g10/tofu.c b/g10/tofu.c
index ba46244..c183fc6 100644
--- a/g10/tofu.c
+++ b/g10/tofu.c
@@ -42,7 +42,6 @@
#include "../common/mkdir_p.h"
#include "gpgsql.h"
#include "../common/status.h"
-#include "sqrtu32.h"
#include "tofu.h"
@@ -2922,19 +2921,18 @@ write_stats_status (estream_t fp,
{
int summary;
int validity;
- unsigned long days;
+ unsigned long days_sq;
/* Use the euclidean distance (m = sqrt(a^2 + b^2)) rather then the
sum of the magnitudes (m = a + b) to ensure a balance between
verified signatures and encrypted messages. */
- days = sqrtu32 (signature_days * signature_days
- + encryption_days * encryption_days);
+ days_sq = signature_days * signature_days + encryption_days * encryption_days;
- if (days < 1)
+ if (days_sq < 1)
validity = 1; /* Key without history. */
- else if (days < 2 * BASIC_TRUST_THRESHOLD)
+ else if (days_sq < (2 * BASIC_TRUST_THRESHOLD) * (2 * BASIC_TRUST_THRESHOLD))
validity = 2; /* Key with too little history. */
- else if (days < 2 * FULL_TRUST_THRESHOLD)
+ else if (days_sq < (2 * FULL_TRUST_THRESHOLD) * (2 * FULL_TRUST_THRESHOLD))
validity = 3; /* Key with enough history for basic trust. */
else
validity = 4; /* Key with a lot of history. */
@@ -3232,9 +3230,9 @@ show_statistics (tofu_dbs_t dbs,
" one message to this key!\n"));
/* Cf. write_stats_status */
- if (sqrtu32 (encryption_count * encryption_count
- + signature_count * signature_count)
- < 2 * BASIC_TRUST_THRESHOLD)
+ if ((encryption_count * encryption_count
+ + signature_count * signature_count)
+ < ((2 * BASIC_TRUST_THRESHOLD) * (2 * BASIC_TRUST_THRESHOLD)))
show_warning = 1;
}
}
diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c
index 0889231..9b43584 100644
--- a/kbx/kbxutil.c
+++ b/kbx/kbxutil.c
@@ -92,7 +92,7 @@ static ARGPARSE_OPTS opts[] = {
{ oDebug, "debug" ,4|16, N_("set debugging flags")},
{ oDebugAll, "debug-all" ,0, N_("enable full debugging")},
- {0} /* end of list */
+ ARGPARSE_end () /* end of list */
};
diff --git a/po/ca.po b/po/ca.po
index 950d95c..3f8f601 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -420,6 +420,9 @@ msgstr ""
msgid "enable ssh support"
msgstr "no és suportat"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
# Gènere? Nombre? ivb
# Werner FIXME: please add translator comment saying *what* is
# uncompressed so we know the gender. jm
@@ -448,6 +451,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr ""
+msgid "selected digest algorithm is invalid\n"
+msgstr "l'algorisme de resum seleccionat no és vàlid\n"
+
#, fuzzy, c-format
#| msgid "NOTE: no default option file `%s'\n"
msgid "Note: no default option file '%s'\n"
@@ -1343,6 +1349,11 @@ msgid "WARNING: %s\n"
msgstr "AVÍS: %s té preferència sobre %s\n"
#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s encara no funciona amb %s\n"
+
+#, fuzzy, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "la clau secreta no està disponible"
@@ -1413,10 +1424,6 @@ msgstr ""
msgid "URL to retrieve public key: "
msgstr "no hi ha cap clau pública corresponent: %s\n"
-#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy, c-format
#| msgid "error reading `%s': %s\n"
msgid "error reading '%s': %s\n"
@@ -1429,17 +1436,9 @@ msgstr "error mentre s'escrivia l'anell «%s»: %s\n"
msgid "Login data (account name): "
msgstr ""
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr ""
-
msgid "Private DO data: "
msgstr ""
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy
msgid "Language preferences: "
msgstr "preferències actualitzades"
@@ -1745,6 +1744,14 @@ msgstr ""
"forçar el xifrat asimètric %s (%d) viola les preferències del destinatari\n"
#, fuzzy, c-format
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "no podeu usar l'algorisme de xifratge «%s» mentre esteu en mode %s\n"
+
+#, fuzzy, c-format
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "AVÍS: %s és una opció desaconsellada.\n"
+
+#, fuzzy, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
"preferences\n"
@@ -1761,8 +1768,9 @@ msgstr ""
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s xifrat per a: «%s»\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "no podeu usar %s mentre esteu en mode %s\n"
#, c-format
@@ -1947,6 +1955,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 "valid values for option '%s':\n"
+msgstr "opcions d'importació no vàlides\n"
+
#, fuzzy
msgid "make a signature"
msgstr "|[fitxer]|crea una signatura"
@@ -2310,10 +2322,6 @@ msgid "show expiration dates during signature listings"
msgstr "No hi ha cap signatura corresponent en l'anell secret\n"
#, fuzzy, c-format
-msgid "valid values for option '%s':\n"
-msgstr "opcions d'importació no vàlides\n"
-
-#, fuzzy, c-format
msgid "unknown TOFU policy '%s'\n"
msgstr "el destinatari predeterminat és desconegut «%s»\n"
@@ -2321,10 +2329,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr ""
#, fuzzy, c-format
-msgid "invalid value for option '%s'\n"
-msgstr "opcions d'importació no vàlides\n"
-
-#, fuzzy, 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"
@@ -2471,9 +2475,6 @@ msgstr "s'està escrivint la clau secreta a «%s»\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "l'algorisme de xifratge triat no és vàlid\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "l'algorisme de resum seleccionat no és vàlid\n"
-
#, fuzzy
msgid "selected compression algorithm is invalid\n"
msgstr "l'algorisme de xifratge triat no és vàlid\n"
@@ -2524,15 +2525,11 @@ 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"
-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 "digest algorithm '%s' may not be used 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 "compression algorithm '%s' may not be used in %s mode\n"
msgstr "no podeu usar l'algorisme de compressió %s mentre esteu en mode %s\n"
#, c-format
@@ -2551,14 +2548,14 @@ msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "no podeu usar %s mentre esteu en mode %s\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "no podeu usar %s mentre esteu en mode %s\n"
#, c-format
@@ -2690,6 +2687,10 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr ""
+#, fuzzy
+msgid "repair keys on import"
+msgstr "mostra empremta"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "es descarta un bloc de tipus %d\n"
@@ -3090,59 +3091,6 @@ msgstr "[revocació]"
msgid "[self-signature]"
msgstr "[autosignatura]"
-#, fuzzy, c-format
-msgid "error allocating memory: %s\n"
-msgstr "error en crear l'anell «%s»: %s\n"
-
-#, fuzzy, c-format
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "clau %08lX: l'algoritme de clau pública no és suportat\n"
-
-#, fuzzy, c-format
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "signatura %s, algorisme de resum %s\n"
-
-#, fuzzy
-msgid " (reordered signatures follow)"
-msgstr "Signatura correcta de \""
-
-#, fuzzy, c-format
-msgid "key %s:\n"
-msgstr "es descarta «%s»: %s\n"
-
-#, fuzzy, c-format
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "L'ID d'usuari «%s» està revocat."
-msgstr[1] "L'ID d'usuari «%s» està revocat."
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "1 signatura no comprovada per falta de clau\n"
-msgstr[1] "1 signatura no comprovada per falta de clau\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d signatures errònies\n"
-msgstr[1] "%d signatures errònies\n"
-
-#, fuzzy, c-format
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "Signatura correcta de \""
-msgstr[1] "Signatura correcta de \""
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
#, fuzzy
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
@@ -3685,6 +3633,14 @@ msgstr "No hi ha res que signar amb la clau %08lX\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "%s no és un joc de caràcters vàlid\n"
+#, fuzzy, c-format
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "error: l'empremta digital és invàlida\n"
+
+#, fuzzy, c-format
+msgid "subkey \"%s\" not found\n"
+msgstr "no s'ha trobat la clau «%s»: %s\n"
+
msgid "Digest: "
msgstr "Resum: "
@@ -4033,6 +3989,10 @@ msgstr ""
"S'està mostrant el photo ID %s de mida %ld per a la clau 0x%08lX (uid %d)\n"
#, fuzzy, c-format
+msgid "invalid value for option '%s'\n"
+msgstr "opcions d'importació no vàlides\n"
+
+#, fuzzy, c-format
msgid "preference '%s' duplicated\n"
msgstr "la preferència %c%lu és duplicada\n"
@@ -4531,6 +4491,20 @@ msgstr[0] "%d signatures errònies\n"
msgstr[1] "%d signatures errònies\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d signatures errònies\n"
+msgstr[1] "%d signatures errònies\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "1 signatura no comprovada per falta de clau\n"
+msgstr[1] "1 signatura no comprovada per falta de clau\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4818,6 +4792,11 @@ msgstr "[incert]"
msgid " aka \"%s\""
msgstr " alias \""
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr "AVÍS: Aquesta clau no ve certificada per una signatura de confiança!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "Aquesta signatura va caducar el %s\n"
@@ -5387,6 +5366,10 @@ msgstr "no s'han pogut obrir les dades signades `%s'\n"
msgid "can't open signed data fd=%d: %s\n"
msgstr "no s'han pogut obrir les dades signades `%s'\n"
+#, fuzzy, c-format
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "clau %08lX: sense ID\n"
+
# Indi? ivb
# Yeh... jm
#, fuzzy, c-format
@@ -5566,6 +5549,11 @@ msgstr ""
msgid "WARNING: signature digest conflict in message\n"
msgstr "AVÍS: conflicte de signatures digest en el missatge\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "no podeu usar %s mentre esteu en mode %s\n"
+
#, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr ""
@@ -8420,6 +8408,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr ""
#, fuzzy, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "error en la lectura de «%s»: %s\n"
+
+#, fuzzy, c-format
+msgid "error allocating memory: %s\n"
+msgstr "error en crear l'anell «%s»: %s\n"
+
+#, fuzzy, c-format
msgid "error printing log line: %s\n"
msgstr "error mentre s'escrivia l'anell «%s»: %s\n"
@@ -8527,10 +8523,6 @@ msgid "error reading HTTP response for '%s': %s\n"
msgstr "error en la lectura de «%s»: %s\n"
#, fuzzy, c-format
-msgid "error accessing '%s': http status %u\n"
-msgstr "error en la lectura de «%s»: %s\n"
-
-#, fuzzy, c-format
msgid "error parsing OCSP response for '%s': %s\n"
msgstr "error mentre s'enviava a «%s»: %s\n"
@@ -9148,6 +9140,36 @@ msgid ""
msgstr ""
#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "clau %08lX: l'algoritme de clau pública no és suportat\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "signatura %s, algorisme de resum %s\n"
+
+#, fuzzy
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "Signatura correcta de \""
+
+#, fuzzy
+#~ msgid "key %s:\n"
+#~ msgstr "es descarta «%s»: %s\n"
+
+#, fuzzy
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "L'ID d'usuari «%s» està revocat."
+#~ msgstr[1] "L'ID d'usuari «%s» està revocat."
+
+#, fuzzy
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "Signatura correcta de \""
+#~ msgstr[1] "Signatura correcta de \""
+
+#, fuzzy
#~| 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"
diff --git a/po/cs.po b/po/cs.po
index f0fe2d9..487ccce 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -402,6 +402,9 @@ msgstr "umožnit zadání hesla skrze Emacs"
msgid "enable ssh support"
msgstr "zapnout podporu pro OpenSSH"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
msgid "enable putty support"
msgstr "zapnout podporu pro PuTTY"
@@ -427,6 +430,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr "zadána neplatná úroveň ladění „%s“\n"
+msgid "selected digest algorithm is invalid\n"
+msgstr "vybraný hashovací algoritmus je neplatný\n"
+
#, c-format
msgid "Note: no default option file '%s'\n"
msgstr "Poznámka: neexistuje implicitní soubor s možnostmi „%s“\n"
@@ -1246,6 +1252,11 @@ msgstr ""
msgid "WARNING: %s\n"
msgstr "VAROVÁNÍ: "
+#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s dosud není funkční s %s\n"
+
#, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "OpenPGP karta není dostupná: %s\n"
@@ -1307,10 +1318,6 @@ msgid "URL to retrieve public key: "
msgstr "URL pro získání veřejného klíče: "
#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr "Chyba: URL je příliš dlouhé (limit je %d znaků).\n"
-
-#, c-format
msgid "error reading '%s': %s\n"
msgstr "chyba při čtení „%s“: %s\n"
@@ -1321,17 +1328,9 @@ msgstr "chyba při zápisu do „%s“: %s\n"
msgid "Login data (account name): "
msgstr "Login (jménu účtu): "
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr "Chyba: Login je příliš dlouhý (limit je %d znaků).\n"
-
msgid "Private DO data: "
msgstr "Privátní DO data: "
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr "Chyba: Privátní DO je příliš dlouhé (limit je %d znaků).\n"
-
msgid "Language preferences: "
msgstr "Jazykové předvolby: "
@@ -1613,6 +1612,16 @@ msgid ""
msgstr ""
"VAROVÁNÍ: vyžádaná symetrická šifra %s (%d) nevyhovuje předvolbám příjemce\n"
+#, fuzzy, c-format
+#| msgid "you may not use cipher algorithm '%s' while in %s mode\n"
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "použití šifrovacího algoritmu „%s“ v módu %s není dovoleno\n"
+
+#, fuzzy, c-format
+#| msgid "WARNING: \"%s%s\" is an obsolete option - it has no effect\n"
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "VAROVÁNÍ: „%s%s“ je zastaralý parametr – neúčinkuje\n"
+
#, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
@@ -1629,8 +1638,9 @@ msgstr "vyžádaná symetrická šifra %s (%d) nevyhovuje předvolbám příjemc
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s zašifrovaný pro: „%s“\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "použití %s není v módu %s dovoleno\n"
#, c-format
@@ -1800,6 +1810,11 @@ msgstr "Neplatný klíč %s změněn na platný pomocí --always-non-selfsigned-
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"
+#, fuzzy, c-format
+#| msgid "invalid argument for option \"%.50s\"\n"
+msgid "valid values for option '%s':\n"
+msgstr "neplatný argument u volby „%.50s“\n"
+
msgid "make a signature"
msgstr "vytvořit podpis"
@@ -2138,11 +2153,6 @@ msgstr "ukazovat název souboru s klíči při výpisu klíčů"
msgid "show expiration dates during signature listings"
msgstr "ukazovat data expirace během výpisu podpisů"
-#, fuzzy, c-format
-#| msgid "invalid argument for option \"%.50s\"\n"
-msgid "valid values for option '%s':\n"
-msgstr "neplatný argument u volby „%.50s“\n"
-
#, c-format
msgid "unknown TOFU policy '%s'\n"
msgstr "neznámá TOFU politika „%s“\n"
@@ -2150,11 +2160,6 @@ msgstr "neznámá TOFU politika „%s“\n"
msgid "(use \"help\" to list choices)\n"
msgstr "(možnosti lze vypsat příkazem „help“)\n"
-#, fuzzy, c-format
-#| msgid "invalid argument for option \"%.50s\"\n"
-msgid "invalid value for option '%s'\n"
-msgstr "neplatný argument u volby „%.50s“\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"
@@ -2292,9 +2297,6 @@ msgstr "nelze spustit s nebezpečnou pamětí vzhledem k %s\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "vybraný šifrovací algoritmus je neplatný\n"
-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"
@@ -2342,16 +2344,14 @@ msgstr "neplatné uživatelské předvolby pro komprimaci\n"
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 není dovoleno\n"
-
-#, c-format
-msgid "you may not use digest algorithm '%s' while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use digest algorithm '%s' while in %s mode\n"
+msgid "digest algorithm '%s' may not be used in %s mode\n"
msgstr "použití hashovacího algoritmu „%s“ v módu %s není dovoleno\n"
-#, c-format
-msgid "you may not use compression algorithm '%s' while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use compression algorithm '%s' while in %s mode\n"
+msgid "compression algorithm '%s' may not be used in %s mode\n"
msgstr "použití kompresního algoritmu „%s“ v módu %s není dovoleno\n"
#, c-format
@@ -2369,15 +2369,17 @@ msgstr "symetrické šifrování „%s“ se nepovedlo: %s\n"
msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr "nelze použít --symmetric --encrypt s příkazem --s2k-mode 0\n"
-#, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "nelze použít --symmetric --encrypt v módu %s\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr "nelze použít --symmetric --sign --encrypt s příkazem --s2k-mode 0\n"
-#, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "nelze použít --symmetric --sign --encrypt v módu %s\n"
#, c-format
@@ -2503,6 +2505,11 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr "předpokládat vstup v binárním formátu"
+#, fuzzy
+#| msgid "show key fingerprint"
+msgid "repair keys on import"
+msgstr "vypsat otisk klíče"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "blok typu %d byl přeskočen\n"
@@ -2886,69 +2893,6 @@ msgstr "[revokace]"
msgid "[self-signature]"
msgstr "[podpis klíče jím samým]"
-#, c-format
-msgid "error allocating memory: %s\n"
-msgstr "chyba při alokování paměti: %s\n"
-
-#, fuzzy, c-format
-#| msgid "key %s: unsupported public key algorithm\n"
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "klíč %s: nepodporovaný algoritmus veřejného klíče\n"
-
-#, fuzzy, c-format
-#| msgid "card does not support digest algorithm %s\n"
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "karta nepodporuje hashovací algoritmus %s\n"
-
-#, fuzzy
-#| msgid "Good signature from"
-msgid " (reordered signatures follow)"
-msgstr "Dobrý podpis od"
-
-#, fuzzy, c-format
-#| msgid "key %s: %s\n"
-msgid "key %s:\n"
-msgstr "klíč %s: %s\n"
-
-#, fuzzy, c-format
-#| msgid "User ID \"%s\": %d signature removed\n"
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "Uživatelské ID „%s“: %d podpisů odstraněno\n"
-msgstr[1] "Uživatelské ID „%s“: %d podpisů odstraněno\n"
-msgstr[2] "Uživatelské ID „%s“: %d podpisů odstraněno\n"
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "1 podpis neověřen, protože chybí klíč\n"
-msgstr[1] "1 podpis neověřen, protože chybí klíč\n"
-msgstr[2] "1 podpis neověřen, protože chybí klíč\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d špatných podpisů\n"
-msgstr[1] "%d špatných podpisů\n"
-msgstr[2] "%d špatných podpisů\n"
-
-#, fuzzy, c-format
-#| msgid "Good signature from"
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "Dobrý podpis od"
-msgstr[1] "Dobrý podpis od"
-msgstr[2] "Dobrý podpis od"
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
"keys\n"
@@ -3423,6 +3367,16 @@ msgstr "Nic na podepsání.\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "„%s“ není platná doba expirace podpisu\n"
+#, fuzzy, c-format
+#| msgid "\"%s\" is not a fingerprint\n"
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "„%s“ není otisk\n"
+
+#, fuzzy, c-format
+#| msgid "key \"%s\" not found\n"
+msgid "subkey \"%s\" not found\n"
+msgstr "klíč „%s“ nenalezen\n"
+
msgid "Digest: "
msgstr "Hash: "
@@ -3740,6 +3694,11 @@ msgstr "Podklíč %s je již revokován.\n"
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"
+#, fuzzy, c-format
+#| msgid "invalid argument for option \"%.50s\"\n"
+msgid "invalid value for option '%s'\n"
+msgstr "neplatný argument u volby „%.50s“\n"
+
#, c-format
msgid "preference '%s' duplicated\n"
msgstr "duplicita předvolby „%s“\n"
@@ -4213,6 +4172,22 @@ msgstr[1] "%d dobrých podpisů\n"
msgstr[2] "%d dobrých podpisů\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d špatných podpisů\n"
+msgstr[1] "%d špatných podpisů\n"
+msgstr[2] "%d špatných podpisů\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "1 podpis neověřen, protože chybí klíč\n"
+msgstr[1] "1 podpis neověřen, protože chybí klíč\n"
+msgstr[2] "1 podpis neověřen, protože chybí klíč\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4501,6 +4476,11 @@ msgstr "[nejistý]"
msgid " aka \"%s\""
msgstr " alias „%s“"
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr "VAROVÁNÍ: Tento klíč není certifikován důvěryhodným podpisem!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "Platnost podpisu skončila %s\n"
@@ -5039,6 +5019,11 @@ msgstr "nelze otevřít podepsaná data „%s“\n"
msgid "can't open signed data fd=%d: %s\n"
msgstr "nelze otevřít podepsaná data na deskriptoru=%d: %s\n"
+#, fuzzy, c-format
+#| msgid "certificate is not usable for encryption\n"
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "certifikát není použitelný pro šifrování\n"
+
#, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "anonymní adresát; zkouším tajný klíč %s…\n"
@@ -5222,6 +5207,11 @@ msgstr "%s klíč %s vyžaduje hash o délce %zu nebo více bitů (hash je %s)\
msgid "WARNING: signature digest conflict in message\n"
msgstr "VAROVÁNÍ: konflikt hashe podpisu ve zprávě\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "použití %s není v módu %s dovoleno\n"
+
#, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr "VAROVÁNÍ: podepisovací podklíč %s není křížově certifikován\n"
@@ -7988,6 +7978,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr "„%s“ není platné LDAP URL\n"
#, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "chyba přístupu k „%s“: status HTTP %u\n"
+
+#, c-format
+msgid "error allocating memory: %s\n"
+msgstr "chyba při alokování paměti: %s\n"
+
+#, c-format
msgid "error printing log line: %s\n"
msgstr "chyba při tisknutí řádku protokolu: %s\n"
@@ -8091,10 +8089,6 @@ msgid "error reading HTTP response for '%s': %s\n"
msgstr "chyba při čtení HTTP odpovědi od „%s“: %s\n"
#, c-format
-msgid "error accessing '%s': http status %u\n"
-msgstr "chyba přístupu k „%s“: status HTTP %u\n"
-
-#, 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"
@@ -8701,6 +8695,53 @@ msgstr ""
"Syntaxe: gpg-check-pattern [volby] soubor_se_vzorem\n"
"Prověří heslo zadané na vstupu proti souboru se vzory\n"
+#~ msgid "Error: URL too long (limit is %d characters).\n"
+#~ msgstr "Chyba: URL je příliš dlouhé (limit je %d znaků).\n"
+
+#~ msgid "Error: Login data too long (limit is %d characters).\n"
+#~ msgstr "Chyba: Login je příliš dlouhý (limit je %d znaků).\n"
+
+#~ msgid "Error: Private DO too long (limit is %d characters).\n"
+#~ msgstr "Chyba: Privátní DO je příliš dlouhé (limit je %d znaků).\n"
+
+#, fuzzy
+#~| msgid "key %s: unsupported public key algorithm\n"
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "klíč %s: nepodporovaný algoritmus veřejného klíče\n"
+
+#, fuzzy
+#~| msgid "card does not support digest algorithm %s\n"
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "karta nepodporuje hashovací algoritmus %s\n"
+
+#, fuzzy
+#~| msgid "Good signature from"
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "Dobrý podpis od"
+
+#, fuzzy
+#~| msgid "key %s: %s\n"
+#~ msgid "key %s:\n"
+#~ msgstr "klíč %s: %s\n"
+
+#, fuzzy
+#~| msgid "User ID \"%s\": %d signature removed\n"
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "Uživatelské ID „%s“: %d podpisů odstraněno\n"
+#~ msgstr[1] "Uživatelské ID „%s“: %d podpisů odstraněno\n"
+#~ msgstr[2] "Uživatelské ID „%s“: %d podpisů odstraněno\n"
+
+#, fuzzy
+#~| msgid "Good signature from"
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "Dobrý podpis od"
+#~ msgstr[1] "Dobrý podpis od"
+#~ msgstr[2] "Dobrý podpis od"
+
#~ msgid "new configuration file '%s' created\n"
#~ msgstr "vytvořen nový konfigurační soubor „%s“\n"
diff --git a/po/da.po b/po/da.po
index be65462..3d42b7c 100644
--- a/po/da.po
+++ b/po/da.po
@@ -427,6 +427,9 @@ msgstr ""
msgid "enable ssh support"
msgstr "aktiver ssh-agent-emulering"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
msgid "enable putty support"
msgstr ""
@@ -457,6 +460,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr "ugyldigt fejlsøgningsniveau »%s« angivet\n"
+msgid "selected digest algorithm is invalid\n"
+msgstr "valgt sammendragsalgoritme er ugyldig\n"
+
#, fuzzy, c-format
#| msgid "NOTE: no default option file `%s'\n"
msgid "Note: no default option file '%s'\n"
@@ -1324,6 +1330,11 @@ msgstr ""
msgid "WARNING: %s\n"
msgstr "ADVARSEL: %s overskriver %s\n"
+#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s virker endnu ikke med %s\n"
+
#, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "OpenPGP-kort er ikke tilgængeligt: %s\n"
@@ -1384,10 +1395,6 @@ msgstr "Fejl: Kombineret navn er for langt (begrænsningen er på %d tegn).\n"
msgid "URL to retrieve public key: "
msgstr "Adresse hvor offentlig nøgle skal hentes: "
-#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr "Fejl: Adresse er for lang (begrænsningen er %d tegn).\n"
-
#, fuzzy, c-format
#| msgid "error reading `%s': %s\n"
msgid "error reading '%s': %s\n"
@@ -1401,17 +1408,9 @@ msgstr "fejl ved skrivning af »%s«: %s\n"
msgid "Login data (account name): "
msgstr "Loginddata (kontonavn): "
-#, 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"
-
msgid "Private DO data: "
msgstr "Private DO-data: "
-#, 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"
-
msgid "Language preferences: "
msgstr "Sprogpræferencer: "
@@ -1716,6 +1715,16 @@ msgstr ""
"ADVARSEL: Tvang for symmetrisk chiffer %s (%d) overtræder modtagerens "
"præferencer\n"
+#, fuzzy, c-format
+#| msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "du må ikke bruge chifferalgoritmen »%s« i tilstanden %s\n"
+
+#, fuzzy, c-format
+#| msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "ADVARSEL: »%s« er en forældet indstilling - den har ingen effekt\n"
+
#, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
@@ -1733,8 +1742,9 @@ msgstr ""
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s krypteret for: »%s«\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "du kan ikke bruge %s i tilstanden %s\n"
#, c-format
@@ -1909,6 +1919,11 @@ msgstr "Ugyldig nøgle %s gjort gyldig med --allow-non-selfsigned-uid\n"
msgid "using subkey %s instead of primary key %s\n"
msgstr "bruger undernøgle %s i stedet for primær nøgle %s\n"
+#, fuzzy, c-format
+#| msgid "missing argument for option \"%.50s\"\n"
+msgid "valid values for option '%s':\n"
+msgstr "manglende parameter for indstilling »%.50s«\n"
+
msgid "make a signature"
msgstr "opret en underskrift"
@@ -2267,11 +2282,6 @@ msgid "show expiration dates during signature listings"
msgstr "vis udløbsdatoer under underskriftvisninger"
#, fuzzy, c-format
-#| msgid "missing argument for option \"%.50s\"\n"
-msgid "valid values for option '%s':\n"
-msgstr "manglende parameter for indstilling »%.50s«\n"
-
-#, fuzzy, c-format
#| msgid "unknown option `%s'\n"
msgid "unknown TOFU policy '%s'\n"
msgstr "ukendt tilvalg »%s«\n"
@@ -2280,11 +2290,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr ""
#, fuzzy, c-format
-#| msgid "missing argument for option \"%.50s\"\n"
-msgid "invalid value for option '%s'\n"
-msgstr "manglende parameter for indstilling »%.50s«\n"
-
-#, fuzzy, c-format
#| msgid "NOTE: old default options file `%s' ignored\n"
msgid "Note: old default options file '%s' ignored\n"
msgstr "BEMÆRK: Gammel standardfil for tilvalg »%s« blev ignoreret\n"
@@ -2426,9 +2431,6 @@ msgstr "vil ikke køre med usikker hukommelse på grund af %s\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "valgt chifferalgoritme er ugyldig\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "valgt sammendragsalgoritme er ugyldig\n"
-
msgid "selected compression algorithm is invalid\n"
msgstr "valgt komprimeringsalgoritme er ugyldig\n"
@@ -2475,18 +2477,13 @@ msgid "%s does not yet work with %s\n"
msgstr "%s virker endnu ikke med %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 "du må ikke bruge chifferalgoritmen »%s« i tilstanden %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"
+msgid "digest algorithm '%s' may not be used in %s mode\n"
msgstr "du må ikke bruge sammendragsalgoritmen »%s« i tilstanden %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"
+msgid "compression algorithm '%s' may not be used in %s mode\n"
msgstr "du må ikke bruge komprimeringsalgoritmen »%s« i tilstanden %s\n"
#, c-format
@@ -2505,15 +2502,17 @@ msgstr "symmetrisk kryptering af »%s« mislykkedes: %s\n"
msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr "du kan ikke bruge --symmetric --encrypt med --s2k-mode 0\n"
-#, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "du kan ikke bruge --symmetric --encrypt i tilstanden %s\n"
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"
-#, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "du kan ikke bruge --symmetric --sign --encrypt i tilstanden %s\n"
#, c-format
@@ -2644,6 +2643,11 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr "antag inddata er i binært format"
+#, fuzzy
+#| msgid "show key fingerprint"
+msgid "repair keys on import"
+msgstr "vis nøglefingeraftryk"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr " udelader bloktype %d\n"
@@ -3042,66 +3046,6 @@ msgstr "[tilbagekald]"
msgid "[self-signature]"
msgstr "[egenunderskrift]"
-#, fuzzy, c-format
-#| msgid "error allocating enough memory: %s\n"
-msgid "error allocating memory: %s\n"
-msgstr "fejl ved allokering af nok hukommelse: %s\n"
-
-#, fuzzy, c-format
-#| msgid "key %s: unsupported public key algorithm\n"
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "nøgle %s: ikke understøttet offentlig nøglealgoritme\n"
-
-#, fuzzy, c-format
-#| msgid "card does not support digest algorithm %s\n"
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "kort understøtter ikke sammendragsalgoritme %s\n"
-
-#, fuzzy
-#| msgid "Good signature from"
-msgid " (reordered signatures follow)"
-msgstr "God underskrift fra"
-
-#, fuzzy, c-format
-#| msgid "skipped \"%s\": %s\n"
-msgid "key %s:\n"
-msgstr "udelod »%s«: %s\n"
-
-#, fuzzy, c-format
-#| msgid "User ID \"%s\": %d signature removed\n"
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "Bruger-id »%s«: %d underskrift fjernet\n"
-msgstr[1] "Bruger-id »%s«: %d underskrift fjernet\n"
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "1 underskrift er ikke kontrolleret på grund af en manglende nøgle\n"
-msgstr[1] "1 underskrift er ikke kontrolleret på grund af en manglende nøgle\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d ugyldige underskrifter\n"
-msgstr[1] "%d ugyldige underskrifter\n"
-
-#, fuzzy, c-format
-#| msgid "Good signature from"
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "God underskrift fra"
-msgstr[1] "God underskrift fra"
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
"keys\n"
@@ -3612,6 +3556,16 @@ msgstr "Intet at underskrive med nøgle %s\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "»%s« er ikke et gyldigt underskriftudløb\n"
+#, fuzzy, c-format
+#| msgid "invalid fingerprint"
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "ugyldig fingeraftryk"
+
+#, fuzzy, c-format
+#| msgid "key \"%s\" not found: %s\n"
+msgid "subkey \"%s\" not found\n"
+msgstr "nøglen »%s« blev ikke fundet: %s\n"
+
msgid "Digest: "
msgstr "Sammendrag: "
@@ -3943,6 +3897,11 @@ 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"
#, fuzzy, c-format
+#| msgid "missing argument for option \"%.50s\"\n"
+msgid "invalid value for option '%s'\n"
+msgstr "manglende parameter for indstilling »%.50s«\n"
+
+#, fuzzy, c-format
#| msgid "preference `%s' duplicated\n"
msgid "preference '%s' duplicated\n"
msgstr "præference »%s« duplikeret\n"
@@ -4437,6 +4396,20 @@ msgstr[0] "%d ugyldige underskrifter\n"
msgstr[1] "%d ugyldige underskrifter\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d ugyldige underskrifter\n"
+msgstr[1] "%d ugyldige underskrifter\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "1 underskrift er ikke kontrolleret på grund af en manglende nøgle\n"
+msgstr[1] "1 underskrift er ikke kontrolleret på grund af en manglende nøgle\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4714,6 +4687,12 @@ msgstr "[usikker]"
msgid " aka \"%s\""
msgstr " også kendt som »%s«"
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr ""
+"ADVARSEL: Denne nøgle er ikke certificeret med en troværdig underskrift!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "Underskrift udløbet %s\n"
@@ -5292,6 +5271,11 @@ msgstr "kan ikke åbne underskrevne data »%s«\n"
msgid "can't open signed data fd=%d: %s\n"
msgstr "kan ikke åbne underskrevne data fd=%d: %s\n"
+#, fuzzy, c-format
+#| msgid "certificate is not usable for encryption\n"
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "certifikat kan ikke bruges til kryptering\n"
+
#, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "anonym modtager; prøver hemmelig nøgle %s ...\n"
@@ -5467,6 +5451,11 @@ msgstr "DSA-nøgle %s kræver en %u bit eller større hash\n"
msgid "WARNING: signature digest conflict in message\n"
msgstr "ADVARSEL: konflikt for underskriftssammendrag i besked\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "du kan ikke bruge %s i tilstanden %s\n"
+
#, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr "ADVARSEL: underskriftsundernøgle %s er ikke krydscertificeret\n"
@@ -8412,6 +8401,16 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr ""
#, fuzzy, c-format
+#| msgid "error running `%s': exit status %d\n"
+msgid "error accessing '%s': http status %u\n"
+msgstr "fejl ved kørsel af »%s«: afslutningsstatus %d\n"
+
+#, fuzzy, c-format
+#| msgid "error allocating enough memory: %s\n"
+msgid "error allocating memory: %s\n"
+msgstr "fejl ved allokering af nok hukommelse: %s\n"
+
+#, fuzzy, c-format
#| msgid "error writing to %s: %s\n"
msgid "error printing log line: %s\n"
msgstr "fejl ved skrivning til »%s«: %s\n"
@@ -8534,11 +8533,6 @@ msgid "error reading HTTP response for '%s': %s\n"
msgstr "fejl ved læsning fra %s: %s\n"
#, fuzzy, c-format
-#| msgid "error running `%s': exit status %d\n"
-msgid "error accessing '%s': http status %u\n"
-msgstr "fejl ved kørsel af »%s«: afslutningsstatus %d\n"
-
-#, fuzzy, c-format
#| msgid "error binding socket to `%s': %s\n"
msgid "error parsing OCSP response for '%s': %s\n"
msgstr "fejl ved binding af sokkel til »%s«: %s\n"
@@ -9209,6 +9203,51 @@ msgstr ""
"Syntaks: gpg-check-pattern [tilvalg] mønsterfil\n"
"Kontroller en adgangsfrase angivet på stdin mod mønsterfilen\n"
+#~ msgid "Error: URL too long (limit is %d characters).\n"
+#~ msgstr "Fejl: Adresse er for lang (begrænsningen er %d tegn).\n"
+
+#~ msgid "Error: Login data too long (limit is %d characters).\n"
+#~ msgstr "Fejl: Loginddata er for lange (begrænsningen er %d tegn).\n"
+
+#~ msgid "Error: Private DO too long (limit is %d characters).\n"
+#~ msgstr "Fejl: Privat DO er for lang (begrænsningen er %d tegn).\n"
+
+#, fuzzy
+#~| msgid "key %s: unsupported public key algorithm\n"
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "nøgle %s: ikke understøttet offentlig nøglealgoritme\n"
+
+#, fuzzy
+#~| msgid "card does not support digest algorithm %s\n"
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "kort understøtter ikke sammendragsalgoritme %s\n"
+
+#, fuzzy
+#~| msgid "Good signature from"
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "God underskrift fra"
+
+#, fuzzy
+#~| msgid "skipped \"%s\": %s\n"
+#~ msgid "key %s:\n"
+#~ msgstr "udelod »%s«: %s\n"
+
+#, fuzzy
+#~| msgid "User ID \"%s\": %d signature removed\n"
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "Bruger-id »%s«: %d underskrift fjernet\n"
+#~ msgstr[1] "Bruger-id »%s«: %d underskrift fjernet\n"
+
+#, fuzzy
+#~| msgid "Good signature from"
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "God underskrift fra"
+#~ msgstr[1] "God underskrift fra"
+
#, fuzzy
#~| msgid "new configuration file `%s' created\n"
#~ msgid "new configuration file '%s' created\n"
diff --git a/po/de.po b/po/de.po
index 8a4c0f9..f71602d 100644
--- a/po/de.po
+++ b/po/de.po
@@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gnupg-2.1.0\n"
"Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2017-05-15 16:00+0200\n"
+"PO-Revision-Date: 2017-07-28 18:50+0200\n"
"Last-Translator: Werner Koch <wk@gnupg.org>\n"
"Language-Team: German <de@li.org>\n"
"Language: de\n"
@@ -386,6 +386,9 @@ msgstr "Erlaube die Eingabe einer Passphrase über Emacs"
msgid "enable ssh support"
msgstr "SSH Unterstützung einschalten"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr "Verwende ALGO für SSH Fingerabdrücke"
+
msgid "enable putty support"
msgstr "PuTTY Unterstützung einschalten"
@@ -411,6 +414,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr "ungültige Debugebene `%s' angegeben\n"
+msgid "selected digest algorithm is invalid\n"
+msgstr "Das ausgewählte Hashverfahren ist ungültig\n"
+
#, c-format
msgid "Note: no default option file '%s'\n"
msgstr "Hinweis: Keine voreingestellte Optionendatei '%s' vorhanden\n"
@@ -1228,6 +1234,10 @@ msgid "WARNING: %s\n"
msgstr "WARNUNG: %s\n"
#, c-format
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s is nicht konform mit dem %s Modus\n"
+
+#, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "OpenPGP Karte ist nicht vorhanden: %s\n"
@@ -1289,10 +1299,6 @@ msgid "URL to retrieve public key: "
msgstr "URL um den öffentlichen Schlüssel zu holen: "
#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr "Fehler: URL ist zu lang (Grenze beträgt %d Zeichen).\n"
-
-#, c-format
msgid "error reading '%s': %s\n"
msgstr "Fehler beim Lesen von `%s': %s\n"
@@ -1303,17 +1309,9 @@ msgstr "Fehler beim Schreiben von %s: %s\n"
msgid "Login data (account name): "
msgstr "Logindaten (Kontenname): "
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr "Fehler: Logindaten sind zu lang (Grenze beträgt %d Zeichen).\n"
-
msgid "Private DO data: "
msgstr "Geheime DO-Daten: "
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr "Fehler: Geheime DO-Daten sind zu lang (Grenze beträgt %d Zeichen).\n"
-
msgid "Language preferences: "
msgstr "Spracheinstellungen"
@@ -1605,6 +1603,16 @@ msgstr ""
"%s (%d) verletzt die Empfängervoreinstellungen\n"
#, c-format
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr ""
+"Das Verschlüsselungsverfahren %s darf im %s Modus nicht verwendet werden.\n"
+
+#, c-format
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr ""
+"WARNUNG: Schlüssel %s ist zur Verschlüsselung im %s Modus nicht geeignet.\n"
+
+#, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
"preferences\n"
@@ -1623,8 +1631,8 @@ msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s verschlüsselt für: %s\n"
#, c-format
-msgid "you may not use %s while in %s mode\n"
-msgstr "Die Benutzung von %s ist im %s-Modus nicht erlaubt.\n"
+msgid "option '%s' may not be used in %s mode\n"
+msgstr "Die Benutzung der Option \"%s\" ist im %s-Modus nicht erlaubt.\n"
#, c-format
msgid "%s encrypted data\n"
@@ -1788,6 +1796,10 @@ msgstr ""
msgid "using subkey %s instead of primary key %s\n"
msgstr "der Unterschlüssel %s wird anstelle des Hauptschlüssels %s verwendet\n"
+#, c-format
+msgid "valid values for option '%s':\n"
+msgstr "Gültige Argumente für Option '%s':\n"
+
msgid "make a signature"
msgstr "Eine Signatur erzeugen"
@@ -2106,10 +2118,6 @@ msgid "show expiration dates during signature listings"
msgstr "Das Ablaufdatum mit den Signaturen anlisten"
#, c-format
-msgid "valid values for option '%s':\n"
-msgstr "Gültige Argumente für Option '%s':\n"
-
-#, c-format
msgid "unknown TOFU policy '%s'\n"
msgstr "Unbekannte TOFU Regel '%s'\n"
@@ -2117,10 +2125,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr "(\"help\" um mögliche Werte anzuzeigen)\n"
#, c-format
-msgid "invalid value for option '%s'\n"
-msgstr "Ungültiges Argument für Option '%s'\n"
-
-#, c-format
msgid "Note: old default options file '%s' ignored\n"
msgstr "Hinweis: Alte voreingestellte Optionendatei '%s' wurde ignoriert\n"
@@ -2257,9 +2261,6 @@ msgstr "Startet nicht mit unsicherem Speicher, wegen Option %s\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "Das ausgewählte Verschlüsselungsverfahren ist ungültig\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "Das ausgewählte Hashverfahren ist ungültig\n"
-
msgid "selected compression algorithm is invalid\n"
msgstr "Das ausgewählte Komprimierungsverfahren ist ungültig\n"
@@ -2304,19 +2305,13 @@ 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"
-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"
-msgstr "Die Benutzung der Hashmethode %s ist im %s-Modus nicht erlaubt.\n"
+msgid "digest algorithm '%s' may not be used 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 "compression algorithm '%s' may not be used in %s mode\n"
msgstr ""
-"Die Benutzung des Komprimierverfahren %s ist im %s-Modus nicht erlaubt.\n"
+"Die Benutzung des Komprimierverfahren %s ist im %s Modus nicht erlaubt.\n"
#, c-format
msgid "failed to initialize the TrustDB: %s\n"
@@ -2335,8 +2330,8 @@ msgstr ""
"--symmetric --encrypt kann nicht zusammen mit --s2k-mode 0 verwendet werden\n"
#, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
-msgstr "Im %s-Modus kann --symmetric --encrypt nicht verwendet werden.\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
+msgstr "Im %s Modus kann --symmetric --encrypt nicht verwendet werden.\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr ""
@@ -2344,9 +2339,9 @@ msgstr ""
"werden\n"
#, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr ""
-"Im %s-Modus kann --symmetric --sign --encrypt nicht verwendet werden.\n"
+"Im %s Modus kann --symmetric --sign --encrypt nicht verwendet werden.\n"
#, c-format
msgid "keyserver send failed: %s\n"
@@ -2469,6 +2464,9 @@ msgstr "Import-Filter anwenden und Schlüssel direkt exportieren"
msgid "assume the GnuPG key backup format"
msgstr "Eingabedaten sind im GnuPG Datensicherungsformat für Schlüssel"
+msgid "repair keys on import"
+msgstr "Schlüssel beim Import reparieren"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "überspringe den Block vom Typ %d\n"
@@ -2863,62 +2861,6 @@ msgstr "[Widerruf]"
msgid "[self-signature]"
msgstr "[Eigenbeglaubigung]"
-#, c-format
-msgid "error allocating memory: %s\n"
-msgstr "Fehler beim Allozieren von Speicher: %s\n"
-
-#, c-format
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr ""
-"Die Signatur mit den nicht unterstützten Public-Key-Verfahren (%d) kann "
-"nicht geprüft werden: %s\n"
-
-#, c-format
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr ""
-"Die Signatur mit der nicht unterstützten Hashmethode (%d) kann nicht\n"
-"geprüft werden: %s.\n"
-
-msgid " (reordered signatures follow)"
-msgstr " (neu geordnete Signaturen folgen)"
-
-#, c-format
-msgid "key %s:\n"
-msgstr "Schlüssel %s:\n"
-
-#, c-format
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "%d doppelte Signatur entfernt\n"
-msgstr[1] "%d doppelte Signaturen entfernt\n"
-
-#, c-format
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "%d Beglaubigung wegen fehlendem Schlüssel nicht geprüft\n"
-msgstr[1] "%d Beglaubigungen wegen fehlender Schlüssel nicht geprüft\n"
-
-#, c-format
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d falsche Beglaubigung\n"
-msgstr[1] "%d falsche Beglaubigungen\n"
-
-#, c-format
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "%d Signatur neu eingeordnet\n"
-msgstr[1] "%d Signaturen neu eingeordnet\n"
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-"WARNUNG: Es wurden Fehler gefunden aber nur Eigenbeglaubigungen geprüft; um "
-"alle Beglaubigungen zu prüfen das Kommando '%s' verwenden.\n"
-
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
"keys\n"
@@ -3401,6 +3343,14 @@ msgstr "Nichts zu beglaubigen\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "'%s' ist kein gültiges Ablaufdatum\n"
+#, c-format
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "\"%s\" ist kein gültiger Fingerabdruck\n"
+
+#, c-format
+msgid "subkey \"%s\" not found\n"
+msgstr "Unterschlüssel \"%s\" nicht gefunden\n"
+
msgid "Digest: "
msgstr "Digest: "
@@ -3726,6 +3676,10 @@ 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 "invalid value for option '%s'\n"
+msgstr "Ungültiges Argument für Option '%s'\n"
+
+#, c-format
msgid "preference '%s' duplicated\n"
msgstr "Voreinstellung `%s' ist doppelt\n"
@@ -4192,6 +4146,18 @@ msgstr[0] "%d korrekte Signatur\n"
msgstr[1] "%d korrekte Signaturen\n"
#, c-format
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d falsche Beglaubigung\n"
+msgstr[1] "%d falsche Beglaubigungen\n"
+
+#, c-format
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "%d Beglaubigung wegen fehlendem Schlüssel nicht geprüft\n"
+msgstr[1] "%d Beglaubigungen wegen fehlender Schlüssel nicht geprüft\n"
+
+#, c-format
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
msgstr[0] "%d Beglaubigung aufgrund eines Fehlers nicht geprüft\n"
@@ -4465,6 +4431,11 @@ msgid " aka \"%s\""
msgstr " alias \"%s\""
#, c-format
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr ""
+"WARNUNG: Dieser Schlüssel ist zum Signieren im %s Modus nicht geeignet.\n"
+
+#, c-format
msgid "Signature expired %s\n"
msgstr "Diese Signatur ist seit %s verfallen.\n"
@@ -5032,6 +5003,11 @@ msgid "can't open signed data fd=%d: %s\n"
msgstr "kann signierte Daten auf fd=%d nicht öffnen: %s\n"
#, c-format
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr ""
+"Hinweis: Schlüssel \"%s\" ist zum Verschlüsseln im %s Modus nicht geeignet.\n"
+
+#, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "Ungenannter Empfänger; Versuch mit geheimen Schlüssel %s ...\n"
@@ -5218,6 +5194,11 @@ msgid "WARNING: signature digest conflict in message\n"
msgstr "WARNUNG: Widersprechende Hashverfahren in der signierten Nachricht\n"
#, c-format
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr ""
+"Schlüssel \"%s\" darf zum Signieren im %s Modus nicht verwendet werden.\n"
+
+#, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr "WARNUNG: Signaturunterschlüssel %s hat keine Rücksignatur\n"
@@ -5880,19 +5861,7 @@ msgstr ""
"WARNUNG: Wir haben nur eine einzige mit diesem Schlüssel signierte Nachricht "
"gesehen.\n"
-#, fuzzy, c-format
-#| msgid ""
-#| "Warning: if you think you've seen more than %ld message signed by this "
-#| "key, then this key might be a forgery! Carefully examine the email "
-#| "address for small variations. If the key is suspect, then use\n"
-#| " %s\n"
-#| "to mark it as being bad.\n"
-#| msgid_plural ""
-#| "Warning: if you think you've seen more than %ld messages signed by this "
-#| "key, then this key might be a forgery! Carefully examine the email "
-#| "address for small variations. If the key is suspect, then use\n"
-#| " %s\n"
-#| "to mark it as being bad.\n"
+#, c-format
msgid ""
"Warning: if you think you've seen more signatures by this key and user id, "
"then this key might be a forgery! Carefully examine the email address for "
@@ -5906,18 +5875,20 @@ msgid_plural ""
" %s\n"
"to mark it as being bad.\n"
msgstr[0] ""
-"WARNUNG: Falls sie glauben, mehr als %ld mit diesem Schlüssel signierte "
-"Nachricht erhalten zu haben, so kann es sich bei diesem Schlüssel um eine "
-"Fälschung handeln! Prüfen Sie die Email-Adresse genau auf kleine "
-"Variationen. Falls Ihnen der Schlüssel suspekt erscheint, so benutzen Sie\n"
-" %s\n"
+"WARNUNG: Falls sie glauben, mehr mit diesem Schlüssel und dieser\n"
+"User-ID signierte Nachricht erhalten zu haben, so kann es sich bei\n"
+"diesem Schlüssel um eine Fälschung handeln! Prüfen Sie die\n"
+"Email-Adresse genau auf kleine Abweichungen. Falls Ihnen der\n"
+"Schlüssel suspekt erscheint, benutzen Sie\n"
+" %s\n"
"um den Schlüssel als Fälschung zu markieren.\n"
msgstr[1] ""
-"WARNUNG: Falls sie glauben, mehr als %ld mit diesem Schlüssel signierte "
-"Nachrichten erhalten zu haben, so kann es sich bei diesem Schlüssel um eine "
-"Fälschung handeln! Prüfen Sie die Email-Adresse genau auf kleine "
-"Variationen. Falls Ihnen der Schlüssel suspekt erscheint, so benutzen Sie\n"
-" %s\n"
+"WARNUNG: Falls sie glauben, mehr mit diesem Schlüssel und diesen\n"
+"User-IDs signierte Nachrichten erhalten zu haben, so kann es sich\n"
+"bei diesem Schlüssel um eine Fälschung handeln! Prüfen Sie die\n"
+"Email-Adressen genau auf kleine Abweichungen. Falls Ihnen der\n"
+"Schlüssel suspekt erscheint, benutzen Sie\n"
+" %s\n"
"um den Schlüssel als Fälschung zu markieren.\n"
#, c-format
@@ -8077,6 +8048,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr "`%s' ist ein ungültiger LDAP URL\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 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"
@@ -8180,10 +8159,6 @@ 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"
@@ -8777,6 +8752,51 @@ msgstr ""
"Syntax: gpg-check-pattern [optionen] Musterdatei\n"
"Die von stdin gelesene Passphrase gegen die Musterdatei prüfen\n"
+#~ msgid "Error: URL too long (limit is %d characters).\n"
+#~ msgstr "Fehler: URL ist zu lang (Grenze beträgt %d Zeichen).\n"
+
+#~ msgid "Error: Login data too long (limit is %d characters).\n"
+#~ msgstr "Fehler: Logindaten sind zu lang (Grenze beträgt %d Zeichen).\n"
+
+#~ msgid "Error: Private DO too long (limit is %d characters).\n"
+#~ msgstr ""
+#~ "Fehler: Geheime DO-Daten sind zu lang (Grenze beträgt %d Zeichen).\n"
+
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr ""
+#~ "Die Signatur mit den nicht unterstützten Public-Key-Verfahren (%d) kann "
+#~ "nicht geprüft werden: %s\n"
+
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr ""
+#~ "Die Signatur mit der nicht unterstützten Hashmethode (%d) kann nicht\n"
+#~ "geprüft werden: %s.\n"
+
+#~ msgid " (reordered signatures follow)"
+#~ msgstr " (neu geordnete Signaturen folgen)"
+
+#~ msgid "key %s:\n"
+#~ msgstr "Schlüssel %s:\n"
+
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "%d doppelte Signatur entfernt\n"
+#~ msgstr[1] "%d doppelte Signaturen entfernt\n"
+
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "%d Signatur neu eingeordnet\n"
+#~ msgstr[1] "%d Signaturen neu eingeordnet\n"
+
+#~ msgid ""
+#~ "Warning: errors found and only checked self-signatures, run '%s' to check "
+#~ "all signatures.\n"
+#~ msgstr ""
+#~ "WARNUNG: Es wurden Fehler gefunden aber nur Eigenbeglaubigungen geprüft; "
+#~ "um alle Beglaubigungen zu prüfen das Kommando '%s' verwenden.\n"
+
#~ msgid "new configuration file '%s' created\n"
#~ msgstr "Neue Konfigurationsdatei `%s' erstellt\n"
diff --git a/po/el.po b/po/el.po
index 96adc8e..b8a505b 100644
--- a/po/el.po
+++ b/po/el.po
@@ -393,6 +393,9 @@ msgstr ""
msgid "enable ssh support"
msgstr "δεν υποστηρίζεται"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable putty support"
@@ -418,6 +421,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr ""
+msgid "selected digest algorithm is invalid\n"
+msgstr "ο επιλεγμένος αλγόριθμος περίληψης δεν είναι έγκυρος\n"
+
#, fuzzy, c-format
#| msgid "NOTE: no default option file `%s'\n"
msgid "Note: no default option file '%s'\n"
@@ -1280,6 +1286,11 @@ msgid "WARNING: %s\n"
msgstr "ΠΡΟΕΙΔΟΠΟΙΗΣΗ: το %s παρακάμπτει το %s\n"
#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "το %s ακόμα δε λειτουργεί μαζί με το %s\n"
+
+#, fuzzy, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "το μυστικό κλειδί δεν είναι διαθέσιμο"
@@ -1347,10 +1358,6 @@ msgstr ""
msgid "URL to retrieve public key: "
msgstr "κανένα αντίστιχο δημόσιο κλειδί: %s\n"
-#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy, c-format
#| msgid "error reading `%s': %s\n"
msgid "error reading '%s': %s\n"
@@ -1363,17 +1370,9 @@ msgstr "αδυναμία εγγραφής της κλειδοθήκης `%s': %s
msgid "Login data (account name): "
msgstr ""
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr ""
-
msgid "Private DO data: "
msgstr ""
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy
msgid "Language preferences: "
msgstr "αναωεωμένες επιλογές"
@@ -1680,6 +1679,14 @@ msgstr ""
"επιλογές του παραλήπτη\n"
#, fuzzy, c-format
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "απαγορεύετε η χρήση του κρυπταλγόριθμου \"%s\" στην κατάσταση %s\n"
+
+#, fuzzy, c-format
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "ΠΡΟΕΙΔΟΠΟΙΗΣΗ: \"%s\" είναι μια μη συνειστώμενη επιλογή\n"
+
+#, fuzzy, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
"preferences\n"
@@ -1697,8 +1704,9 @@ msgstr ""
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s κρυπτογραφήθηκε για: \"%s\"\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "απαγορεύετε η χρήση του %s στην κατάσταση %s.\n"
#, c-format
@@ -1879,6 +1887,10 @@ msgstr ""
msgid "using subkey %s instead of primary key %s\n"
msgstr "χρήση του δευτερεύοντος κλειδιού %08lX αντί του πρωτεύοντος %08lX\n"
+#, fuzzy, c-format
+msgid "valid values for option '%s':\n"
+msgstr "μη έγκυρες επιλογές ειγαγωγής\n"
+
#, fuzzy
msgid "make a signature"
msgstr "δημιουργία μιας μη προσαρτημένης υπογραφής"
@@ -2231,10 +2243,6 @@ msgid "show expiration dates during signature listings"
msgstr "Δεν βρέθηκε αντίστοιχη υπογραφή στη μυστική κλειδοθήκη\n"
#, fuzzy, c-format
-msgid "valid values for option '%s':\n"
-msgstr "μη έγκυρες επιλογές ειγαγωγής\n"
-
-#, fuzzy, c-format
msgid "unknown TOFU policy '%s'\n"
msgstr "άγνωστος προκαθορισμένος παραλήπτης `%s'\n"
@@ -2242,10 +2250,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr ""
#, fuzzy, c-format
-msgid "invalid value for option '%s'\n"
-msgstr "μη έγκυρες επιλογές ειγαγωγής\n"
-
-#, fuzzy, c-format
#| msgid "NOTE: old default options file `%s' ignored\n"
msgid "Note: old default options file '%s' ignored\n"
msgstr "ΣΗΜΕΙΩΣΗ: αγνοήθηκε το παλιό αρχείο προκαθορισμένων επιλογών `%s'\n"
@@ -2390,9 +2394,6 @@ msgstr "εγγραφή του μυστικού κλειδιού στο `%s'\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "ο επιλεγμένος αλγόριθμος κρυπτογράφησης δεν είναι έγκυρος\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "ο επιλεγμένος αλγόριθμος περίληψης δεν είναι έγκυρος\n"
-
#, fuzzy
msgid "selected compression algorithm is invalid\n"
msgstr "ο επιλεγμένος αλγόριθμος κρυπτογράφησης δεν είναι έγκυρος\n"
@@ -2443,16 +2444,12 @@ 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"
-msgstr "απαγορεύετε η χρήση του κρυπταλγόριθμου \"%s\" στην κατάσταση %s\n"
-
-#, fuzzy, c-format
-msgid "you may not use digest algorithm '%s' while in %s mode\n"
+msgid "digest algorithm '%s' may not be used 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 "compression algorithm '%s' may not be used in %s mode\n"
msgstr ""
"απαγορεύετε η χρήση του αλγόριθμου συμπίεσης \"%s\" στην κατάσταση %s\n"
@@ -2473,14 +2470,14 @@ msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "απαγορεύετε η χρήση του %s στην κατάσταση %s.\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "απαγορεύετε η χρήση του %s στην κατάσταση %s.\n"
#, c-format
@@ -2611,6 +2608,10 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr ""
+#, fuzzy
+msgid "repair keys on import"
+msgstr "απεικόνιση του fingerprint"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "παράλειψη τμήματος του τύπου %d\n"
@@ -3004,59 +3005,6 @@ msgstr "[ανάκληση]"
msgid "[self-signature]"
msgstr "[ιδιο-υπογραφή]"
-#, fuzzy, c-format
-msgid "error allocating memory: %s\n"
-msgstr "αδυναμία δημιουργίας της κλειδοθήκης `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "κλειδί %08lX: μη υποστηριζόμενος αλγόριθμος δημοσίου κλειδιού\n"
-
-#, fuzzy, c-format
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "%s υπογραφή, αλγόριθμος περίληψης %s\n"
-
-#, fuzzy
-msgid " (reordered signatures follow)"
-msgstr "Καλή υπογραφή από \""
-
-#, fuzzy, c-format
-msgid "key %s:\n"
-msgstr "παραλείφθηκε `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "Το user ID \"%s\" ανακαλείτε."
-msgstr[1] "Το user ID \"%s\" ανακαλείτε."
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "1 υπογραφή δεν ελέγχθηκε λόγω χαμένου κλειδιού\n"
-msgstr[1] "1 υπογραφή δεν ελέγχθηκε λόγω χαμένου κλειδιού\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d κακές υπογραφές\n"
-msgstr[1] "%d κακές υπογραφές\n"
-
-#, fuzzy, c-format
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "Καλή υπογραφή από \""
-msgstr[1] "Καλή υπογραφή από \""
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
#, fuzzy
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
@@ -3591,6 +3539,14 @@ msgstr "Τίποτα για να υπογραφεί με το κλειδί %08l
msgid "'%s' is not a valid expiration time\n"
msgstr "το %s δεν είναι έγκυρο σετ χαρακτήρων\n"
+#, fuzzy, c-format
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "σφάλμα: μη έγκυρο αποτύπωμα\n"
+
+#, fuzzy, c-format
+msgid "subkey \"%s\" not found\n"
+msgstr "το κλειδί '%s' δε βρέθηκε: %s\n"
+
msgid "Digest: "
msgstr "Περίληψη: "
@@ -3935,6 +3891,10 @@ 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 "invalid value for option '%s'\n"
+msgstr "μη έγκυρες επιλογές ειγαγωγής\n"
+
+#, fuzzy, c-format
msgid "preference '%s' duplicated\n"
msgstr "η προεπιλογή %c%lu αντιγράφτηκε\n"
@@ -4428,6 +4388,20 @@ msgstr[0] "%d κακές υπογραφές\n"
msgstr[1] "%d κακές υπογραφές\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d κακές υπογραφές\n"
+msgstr[1] "%d κακές υπογραφές\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "1 υπογραφή δεν ελέγχθηκε λόγω χαμένου κλειδιού\n"
+msgstr[1] "1 υπογραφή δεν ελέγχθηκε λόγω χαμένου κλειδιού\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4708,6 +4682,13 @@ msgstr "[αβέβαιο]"
msgid " aka \"%s\""
msgstr " γνωστό σαν \""
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr ""
+"ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Αυτό το κλειδί δεν έχει πιστοποιηθεί με εμπιστεύσιμη "
+"υπογραφή!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "Υπογραφή έληξε στις %s.\n"
@@ -5272,6 +5253,10 @@ msgid "can't open signed data fd=%d: %s\n"
msgstr "αδυναμία πρόσβασης υπογεγραμμένων δεδομένων `%s'\n"
#, fuzzy, c-format
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "κλειδί %08lX: δεν υπάρχει αυτό το user ID\n"
+
+#, fuzzy, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "ανώνυμος παραλήπτης· δοκιμή μυστικού κλειδιού %08lX ...\n"
@@ -5447,6 +5432,11 @@ msgid "WARNING: signature digest conflict in message\n"
msgstr "ΠΡΟΕΙΔΟΠΟΙΗΣΗ: σύγκρουση υπογραφής περίληψης στο μήνυμα\n"
#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "απαγορεύετε η χρήση του %s στην κατάσταση %s.\n"
+
+#, fuzzy, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr ""
"ΠΡΟΕΙΔΟΠΟΙΗΣΗ: το υπογράφων υποκλειδί %08lX δεν έχει κατ' αντιπαράσταση "
@@ -8243,6 +8233,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr ""
#, fuzzy, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "σφάλμα κατά την ανάγνωση του `%s': %s\n"
+
+#, fuzzy, c-format
+msgid "error allocating memory: %s\n"
+msgstr "αδυναμία δημιουργίας της κλειδοθήκης `%s': %s\n"
+
+#, fuzzy, c-format
msgid "error printing log line: %s\n"
msgstr "αδυναμία εγγραφής της κλειδοθήκης `%s': %s\n"
@@ -8350,10 +8348,6 @@ msgid "error reading HTTP response for '%s': %s\n"
msgstr "σφάλμα κατά την ανάγνωση του `%s': %s\n"
#, fuzzy, c-format
-msgid "error accessing '%s': http status %u\n"
-msgstr "σφάλμα κατά την ανάγνωση του `%s': %s\n"
-
-#, fuzzy, c-format
msgid "error parsing OCSP response for '%s': %s\n"
msgstr "σφάλμα στη αποστολή προς το `%s': %s\n"
@@ -8971,6 +8965,36 @@ msgid ""
msgstr ""
#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "κλειδί %08lX: μη υποστηριζόμενος αλγόριθμος δημοσίου κλειδιού\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "%s υπογραφή, αλγόριθμος περίληψης %s\n"
+
+#, fuzzy
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "Καλή υπογραφή από \""
+
+#, fuzzy
+#~ msgid "key %s:\n"
+#~ msgstr "παραλείφθηκε `%s': %s\n"
+
+#, fuzzy
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "Το user ID \"%s\" ανακαλείτε."
+#~ msgstr[1] "Το user ID \"%s\" ανακαλείτε."
+
+#, fuzzy
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "Καλή υπογραφή από \""
+#~ msgstr[1] "Καλή υπογραφή από \""
+
+#, fuzzy
#~| msgid "new configuration file `%s' created\n"
#~ msgid "new configuration file '%s' created\n"
#~ msgstr "δημιουργήθηκε νέο αρχείο επιλογών `%s'\n"
diff --git a/po/eo.po b/po/eo.po
index 8ee1d6b..c52dbad 100644
--- a/po/eo.po
+++ b/po/eo.po
@@ -395,6 +395,9 @@ msgstr ""
msgid "enable ssh support"
msgstr "ne realigita"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable putty support"
@@ -420,6 +423,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr ""
+msgid "selected digest algorithm is invalid\n"
+msgstr "elektita kompendi-metodo ne validas\n"
+
#, fuzzy, c-format
#| msgid "NOTE: no default option file `%s'\n"
msgid "Note: no default option file '%s'\n"
@@ -1284,6 +1290,10 @@ msgid "WARNING: %s\n"
msgstr "AVERTO: %s nuligas %s\n"
#, fuzzy, c-format
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s ne havas sencon kun %s!\n"
+
+#, fuzzy, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "sekreta ŝlosilo ne havebla"
@@ -1351,10 +1361,6 @@ msgstr ""
msgid "URL to retrieve public key: "
msgstr "skribas publikan ŝlosilon al '%s'\n"
-#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy, c-format
#| msgid "error reading `%s': %s\n"
msgid "error reading '%s': %s\n"
@@ -1367,17 +1373,9 @@ msgstr "eraro dum skribado de ŝlosilaro '%s': %s\n"
msgid "Login data (account name): "
msgstr ""
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr ""
-
msgid "Private DO data: "
msgstr ""
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy
msgid "Language preferences: "
msgstr "aktualigitaj preferoj"
@@ -1680,6 +1678,14 @@ msgid ""
msgstr "NOTO: ĉifrad-metodo %d ne trovita en preferoj\n"
#, fuzzy, c-format
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "Tiu komando ne eblas en la reĝimo %s.\n"
+
+#, fuzzy, c-format
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "AVERTO: '%s' estas malplena dosiero\n"
+
+#, fuzzy, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
"preferences\n"
@@ -1694,7 +1700,7 @@ msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s-ĉifrita por: %s\n"
#, fuzzy, c-format
-msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "Tiu komando ne eblas en la reĝimo %s.\n"
#, c-format
@@ -1865,6 +1871,10 @@ msgstr "Nevalida ŝlosilo %08lX validigita per --always-trust\n"
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 "valid values for option '%s':\n"
+msgstr "nevalida kiraso"
+
#, fuzzy
msgid "make a signature"
msgstr "fari apartan subskribon"
@@ -2215,10 +2225,6 @@ msgid "show expiration dates during signature listings"
msgstr "Mankas responda subskribo en sekreta ŝlosilaro\n"
#, fuzzy, c-format
-msgid "valid values for option '%s':\n"
-msgstr "nevalida kiraso"
-
-#, fuzzy, c-format
msgid "unknown TOFU policy '%s'\n"
msgstr "nekonata implicita ricevonto '%s'\n"
@@ -2226,10 +2232,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr ""
#, fuzzy, c-format
-msgid "invalid value for option '%s'\n"
-msgstr "nevalida kiraso"
-
-#, fuzzy, c-format
msgid "Note: old default options file '%s' ignored\n"
msgstr "NOTO: mankas implicita opcio-dosiero '%s'\n"
@@ -2375,9 +2377,6 @@ msgstr "skribas sekretan ŝlosilon al '%s'\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "elektita ĉifrad-metodo ne validas\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "elektita kompendi-metodo ne validas\n"
-
#, fuzzy
msgid "selected compression algorithm is invalid\n"
msgstr "elektita ĉifrad-metodo ne validas\n"
@@ -2433,15 +2432,11 @@ 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"
-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 "digest algorithm '%s' may not be used 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 "compression algorithm '%s' may not be used in %s mode\n"
msgstr "Tiu komando ne eblas en la reĝimo %s.\n"
#, c-format
@@ -2459,14 +2454,14 @@ msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "Tiu komando ne eblas en la reĝimo %s.\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "Tiu komando ne eblas en la reĝimo %s.\n"
#, fuzzy, c-format
@@ -2595,6 +2590,10 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr ""
+#, fuzzy
+msgid "repair keys on import"
+msgstr "montri fingrospuron"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "ignoras blokon de speco %d\n"
@@ -2979,59 +2978,6 @@ msgstr "[revoko]"
msgid "[self-signature]"
msgstr "[mem-subskribo]"
-#, fuzzy, c-format
-msgid "error allocating memory: %s\n"
-msgstr "eraro dum kreado de ŝlosilaro '%s': %s\n"
-
-#, fuzzy, c-format
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "ŝlosilo %08lX: nerealigita publikŝlosila metodo\n"
-
-#, fuzzy, c-format
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "%s-subskribo de: %s\n"
-
-#, fuzzy
-msgid " (reordered signatures follow)"
-msgstr "Bona subskribo de \""
-
-#, fuzzy, c-format
-msgid "key %s:\n"
-msgstr "ignoris '%s': %s\n"
-
-#, fuzzy, c-format
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "Uzantidentigilo \"%s\" estas revokita.\n"
-msgstr[1] "Uzantidentigilo \"%s\" estas revokita.\n"
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "1 subskribo ne kontrolita pro manko de ŝlosilo\n"
-msgstr[1] "1 subskribo ne kontrolita pro manko de ŝlosilo\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d malbonaj subskriboj\n"
-msgstr[1] "%d malbonaj subskriboj\n"
-
-#, fuzzy, c-format
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "Bona subskribo de \""
-msgstr[1] "Bona subskribo de \""
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
#, fuzzy
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
@@ -3578,6 +3524,14 @@ msgstr "Nenio por subskribi per ŝlosilo %08lX\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "%s ne estas valida signaro\n"
+#, fuzzy, c-format
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "%s: nevalida dosiero-versio %d\n"
+
+#, fuzzy, c-format
+msgid "subkey \"%s\" not found\n"
+msgstr "ŝlosilo '%s' ne trovita: %s\n"
+
msgid "Digest: "
msgstr ""
@@ -3910,6 +3864,10 @@ msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
msgstr ""
#, fuzzy, c-format
+msgid "invalid value for option '%s'\n"
+msgstr "nevalida kiraso"
+
+#, fuzzy, c-format
msgid "preference '%s' duplicated\n"
msgstr "prefero %c%lu ripetita\n"
@@ -4401,6 +4359,20 @@ msgstr[0] "%d malbonaj subskriboj\n"
msgstr[1] "%d malbonaj subskriboj\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d malbonaj subskriboj\n"
+msgstr[1] "%d malbonaj subskriboj\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "1 subskribo ne kontrolita pro manko de ŝlosilo\n"
+msgstr[1] "1 subskribo ne kontrolita pro manko de ŝlosilo\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4688,6 +4660,11 @@ msgid " aka \"%s\""
msgstr " alinome \""
#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr "AVERTO: Ĉi tiu ŝlosilo ne estas atestita kun fidata subskribo!\n"
+
+#, fuzzy, c-format
msgid "Signature expired %s\n"
msgstr "Ĉi tiu ŝlosilo eksvalidiĝos je %s.\n"
@@ -5243,6 +5220,10 @@ msgid "can't open signed data fd=%d: %s\n"
msgstr "ne povas malfermi subskribitan dosieron '%s'\n"
#, fuzzy, c-format
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "ŝlosilo %08lX: mankas uzantidentigilo\n"
+
+#, fuzzy, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "nenomita ricevonto; provas per sekreta ŝlosilo %08lX ...\n"
@@ -5411,6 +5392,10 @@ msgstr ""
msgid "WARNING: signature digest conflict in message\n"
msgstr ""
+#, fuzzy, c-format
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "Tiu komando ne eblas en la reĝimo %s.\n"
+
#, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr ""
@@ -8191,6 +8176,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr ""
#, fuzzy, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "eraro dum legado de '%s': %s\n"
+
+#, fuzzy, c-format
+msgid "error allocating memory: %s\n"
+msgstr "eraro dum kreado de ŝlosilaro '%s': %s\n"
+
+#, fuzzy, c-format
msgid "error printing log line: %s\n"
msgstr "eraro dum skribado de ŝlosilaro '%s': %s\n"
@@ -8298,10 +8291,6 @@ msgid "error reading HTTP response for '%s': %s\n"
msgstr "eraro dum legado de '%s': %s\n"
#, fuzzy, c-format
-msgid "error accessing '%s': http status %u\n"
-msgstr "eraro dum legado de '%s': %s\n"
-
-#, fuzzy, c-format
msgid "error parsing OCSP response for '%s': %s\n"
msgstr "eraro dum sendo al '%s': %s\n"
@@ -8918,6 +8907,36 @@ msgid ""
msgstr ""
#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "ŝlosilo %08lX: nerealigita publikŝlosila metodo\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "%s-subskribo de: %s\n"
+
+#, fuzzy
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "Bona subskribo de \""
+
+#, fuzzy
+#~ msgid "key %s:\n"
+#~ msgstr "ignoris '%s': %s\n"
+
+#, fuzzy
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "Uzantidentigilo \"%s\" estas revokita.\n"
+#~ msgstr[1] "Uzantidentigilo \"%s\" estas revokita.\n"
+
+#, fuzzy
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "Bona subskribo de \""
+#~ msgstr[1] "Bona subskribo de \""
+
+#, fuzzy
#~ msgid "new configuration file '%s' created\n"
#~ msgstr "%s: nova opcio-dosiero kreita\n"
diff --git a/po/es.po b/po/es.po
index abc9b79..a9eb67b 100644
--- a/po/es.po
+++ b/po/es.po
@@ -441,6 +441,9 @@ msgstr ""
msgid "enable ssh support"
msgstr "permitir emulación de ssh-agent"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable putty support"
@@ -473,6 +476,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr "el nivel de depuración `%s` no es válido\n"
+msgid "selected digest algorithm is invalid\n"
+msgstr "el algoritmo de resumen seleccionado no inválido\n"
+
#, fuzzy, c-format
#| msgid "NOTE: no default option file `%s'\n"
msgid "Note: no default option file '%s'\n"
@@ -1342,6 +1348,11 @@ msgstr ""
msgid "WARNING: %s\n"
msgstr "ATENCION: "
+#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s aún no funciona con %s\n"
+
#, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "tarjeta OpenPGP no disponible: %s\n"
@@ -1402,10 +1413,6 @@ 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: "
-#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr "Error: URL demasiado larga (el máximo son %d caracteres).\n"
-
#, fuzzy, c-format
#| msgid "error reading `%s': %s\n"
msgid "error reading '%s': %s\n"
@@ -1419,18 +1426,9 @@ msgstr "error escribiendo `%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"
-
msgid "Private DO data: "
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"
-
msgid "Language preferences: "
msgstr "Preferencias de idioma: "
@@ -1734,6 +1732,16 @@ msgstr ""
"AVISO: forzar el cifrado simétrico %s (%d) viola las preferencias\n"
"del destinatario\n"
+#, fuzzy, c-format
+#| msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "no puede usar el cifrado `%s' en modo %s\n"
+
+#, fuzzy, c-format
+#| msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "ATENCIÓN: \"%s\" es una opción obsoleta - no tiene efecto\n"
+
#, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
@@ -1752,8 +1760,9 @@ msgstr ""
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s cifrado para: \"%s\"\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "no puede usar %s en modo %s\n"
#, c-format
@@ -1928,6 +1937,11 @@ msgstr "Clave %s inválida hecha válida mediante --allow-non-selfsigned-uid\n"
msgid "using subkey %s instead of primary key %s\n"
msgstr "usando subclave %s en vez de clave primaria %s\n"
+#, fuzzy, c-format
+#| msgid "missing argument for option \"%.50s\"\n"
+msgid "valid values for option '%s':\n"
+msgstr "falta parámetro para la opción \"%.50s\"\n"
+
msgid "make a signature"
msgstr "crea una firma"
@@ -2293,11 +2307,6 @@ msgid "show expiration dates during signature listings"
msgstr "mostrar fechas de caducidad al listar firmas"
#, fuzzy, c-format
-#| msgid "missing argument for option \"%.50s\"\n"
-msgid "valid values for option '%s':\n"
-msgstr "falta parámetro para la opción \"%.50s\"\n"
-
-#, fuzzy, c-format
#| msgid "unknown option `%s'\n"
msgid "unknown TOFU policy '%s'\n"
msgstr "opción desconocida `%s'\n"
@@ -2306,11 +2315,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr ""
#, fuzzy, c-format
-#| msgid "missing argument for option \"%.50s\"\n"
-msgid "invalid value for option '%s'\n"
-msgstr "falta parámetro para la opción \"%.50s\"\n"
-
-#, fuzzy, 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"
@@ -2452,9 +2456,6 @@ msgstr "no se ejecutará en memoria insegura por %s\n"
msgid "selected cipher algorithm is invalid\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"
-
msgid "selected compression algorithm is invalid\n"
msgstr "el algoritmo de compresión seleccionado es inválido\n"
@@ -2501,18 +2502,13 @@ msgid "%s does not yet work with %s\n"
msgstr "%s aún no funciona 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 "no puede usar el cifrado `%s' en 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"
+msgid "digest algorithm '%s' may not be used in %s mode\n"
msgstr "no puede usar el resumen `%s' en 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"
+msgid "compression algorithm '%s' may not be used in %s mode\n"
msgstr "no puede usar la compresión `%s' en modo %s\n"
#, c-format
@@ -2530,15 +2526,17 @@ msgstr "el cifrado simétrico de `%s' falló: %s\n"
msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr "no puede usar --symetric --encrypt con --s2k-mode 0\n"
-#, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "no puede usar --symetric --encrypt en modo %s\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr "no puede usar --symetric --sign --encrypt con --s2k-mode 0\n"
-#, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "no puede usar --symmetric --sign --encrypt en modo %s\n"
#, c-format
@@ -2673,6 +2671,11 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr "asumir entrada en formato binario"
+#, fuzzy
+#| msgid "show key fingerprint"
+msgid "repair keys on import"
+msgstr "muestra huella dactilar de la clave"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "omitiendo bloque de tipo %d\n"
@@ -3071,66 +3074,6 @@ msgstr "[revocación]"
msgid "[self-signature]"
msgstr "[autofirma]"
-#, fuzzy, c-format
-#| msgid "error allocating enough memory: %s\n"
-msgid "error allocating memory: %s\n"
-msgstr "error reservando memoria: %s\n"
-
-#, fuzzy, c-format
-#| msgid "key %s: unsupported public key algorithm\n"
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "clave %s: algoritmo de clave pública no disponible\n"
-
-#, fuzzy, c-format
-#| msgid "card does not support digest algorithm %s\n"
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "la tarjeta no permite usar el algoritmo de resumen %s\n"
-
-#, fuzzy
-#| msgid "revoke signatures"
-msgid " (reordered signatures follow)"
-msgstr "revoca firmas"
-
-#, fuzzy, c-format
-#| msgid "skipped \"%s\": %s\n"
-msgid "key %s:\n"
-msgstr "omitido \"%s\": %s\n"
-
-#, fuzzy, c-format
-#| msgid "User ID \"%s\": %d signature removed\n"
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "ID de usuario \"%s\": %d firma borrada\n"
-msgstr[1] "ID de usuario \"%s\": %d firma borrada\n"
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "1 firma no comprobada por falta de clave\n"
-msgstr[1] "1 firma no comprobada por falta de clave\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d firmas incorrectas\n"
-msgstr[1] "%d firmas incorrectas\n"
-
-#, fuzzy, c-format
-#| msgid "Good signature from"
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "Firma correcta de"
-msgstr[1] "Firma correcta de"
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
"keys\n"
@@ -3624,6 +3567,16 @@ msgstr "Nada que firmar con la clave %s\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "`%s' no es una fecha de caducidad válida\n"
+#, fuzzy, c-format
+#| msgid "invalid fingerprint"
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "huella dactilar no válida"
+
+#, fuzzy, c-format
+#| msgid "key \"%s\" not found: %s\n"
+msgid "subkey \"%s\" not found\n"
+msgstr "clave \"%s\" no encontrada: %s\n"
+
msgid "Digest: "
msgstr "Resumen: "
@@ -3948,6 +3901,11 @@ 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"
#, fuzzy, c-format
+#| msgid "missing argument for option \"%.50s\"\n"
+msgid "invalid value for option '%s'\n"
+msgstr "falta parámetro para la opción \"%.50s\"\n"
+
+#, fuzzy, c-format
#| msgid "preference `%s' duplicated\n"
msgid "preference '%s' duplicated\n"
msgstr "preferencia `%s' duplicada\n"
@@ -4437,6 +4395,20 @@ msgstr[0] "%d firmas incorrectas\n"
msgstr[1] "%d firmas incorrectas\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d firmas incorrectas\n"
+msgstr[1] "%d firmas incorrectas\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "1 firma no comprobada por falta de clave\n"
+msgstr[1] "1 firma no comprobada por falta de clave\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4715,6 +4687,12 @@ msgstr "[incierto]"
msgid " aka \"%s\""
msgstr " alias \"%s\""
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr ""
+"ATENCIÓN: ¡Esta clave no está certificada por una firma de confianza!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "Firma caducada en %s\n"
@@ -5286,6 +5264,11 @@ msgstr "imposible abrir datos firmados `%s'\n"
msgid "can't open signed data fd=%d: %s\n"
msgstr "imposible abrir datos firmados fd=%d: %s\n"
+#, fuzzy, c-format
+#| msgid "certificate is not usable for encryption\n"
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "el certificado no es utilizable para cifrar\n"
+
#, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "destinatario anónimo; probando clave secreta %s ...\n"
@@ -5463,6 +5446,11 @@ msgstr "la clave DSA %s requiere un resumen de %u bits al menos\n"
msgid "WARNING: signature digest conflict in message\n"
msgstr "AVISO: conflicto con el resumen de la firma del mensaje\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "no puede usar %s en modo %s\n"
+
#, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr "AVISO: la subclave de firmado %s no tiene certificado cruzado\n"
@@ -8433,6 +8421,16 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr ""
#, fuzzy, c-format
+#| msgid "error running `%s': exit status %d\n"
+msgid "error accessing '%s': http status %u\n"
+msgstr "error ejecutando `%s': código de finalización %d\n"
+
+#, fuzzy, c-format
+#| msgid "error allocating enough memory: %s\n"
+msgid "error allocating memory: %s\n"
+msgstr "error reservando memoria: %s\n"
+
+#, fuzzy, c-format
#| msgid "error writing to %s: %s\n"
msgid "error printing log line: %s\n"
msgstr "error escribiendo en %s: %s\n"
@@ -8556,11 +8554,6 @@ msgid "error reading HTTP response for '%s': %s\n"
msgstr "error leyendo de %s: %s\n"
#, fuzzy, c-format
-#| msgid "error running `%s': exit status %d\n"
-msgid "error accessing '%s': http status %u\n"
-msgstr "error ejecutando `%s': código de finalización %d\n"
-
-#, fuzzy, c-format
#| msgid "error binding socket to `%s': %s\n"
msgid "error parsing OCSP response for '%s': %s\n"
msgstr "error enlazando el socket con `%s': %s\n"
@@ -9249,6 +9242,53 @@ msgstr ""
"Compara frase contraseña dada en entrada estándar con un fichero de "
"patrones\n"
+#~ msgid "Error: URL too long (limit is %d characters).\n"
+#~ msgstr "Error: URL demasiado larga (el máximo son %d caracteres).\n"
+
+#~ msgid "Error: Login data too long (limit is %d characters).\n"
+#~ msgstr "Error: el login es demasiado largo (límite de %d caracteres).\n"
+
+#~ 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"
+
+#, fuzzy
+#~| msgid "key %s: unsupported public key algorithm\n"
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "clave %s: algoritmo de clave pública no disponible\n"
+
+#, fuzzy
+#~| msgid "card does not support digest algorithm %s\n"
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "la tarjeta no permite usar el algoritmo de resumen %s\n"
+
+#, fuzzy
+#~| msgid "revoke signatures"
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "revoca firmas"
+
+#, fuzzy
+#~| msgid "skipped \"%s\": %s\n"
+#~ msgid "key %s:\n"
+#~ msgstr "omitido \"%s\": %s\n"
+
+#, fuzzy
+#~| msgid "User ID \"%s\": %d signature removed\n"
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "ID de usuario \"%s\": %d firma borrada\n"
+#~ msgstr[1] "ID de usuario \"%s\": %d firma borrada\n"
+
+#, fuzzy
+#~| msgid "Good signature from"
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "Firma correcta de"
+#~ msgstr[1] "Firma correcta de"
+
#, fuzzy
#~| msgid "new configuration file `%s' created\n"
#~ msgid "new configuration file '%s' created\n"
diff --git a/po/et.po b/po/et.po
index 355d45c..d9381bd 100644
--- a/po/et.po
+++ b/po/et.po
@@ -391,6 +391,9 @@ msgstr ""
msgid "enable ssh support"
msgstr "ei ole toetatud"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable putty support"
@@ -416,6 +419,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr ""
+msgid "selected digest algorithm is invalid\n"
+msgstr "valitud lühendi algoritm ei ole lubatud\n"
+
#, fuzzy, c-format
#| msgid "NOTE: no default option file `%s'\n"
msgid "Note: no default option file '%s'\n"
@@ -1277,6 +1283,11 @@ msgid "WARNING: %s\n"
msgstr "HOIATUS: %s määrab üle %s\n"
#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s ei tööta veel koos %s-ga\n"
+
+#, fuzzy, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "salajane võti ei ole kättesaadav"
@@ -1344,10 +1355,6 @@ msgstr ""
msgid "URL to retrieve public key: "
msgstr "vastavat avalikku võtit pole: %s\n"
-#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy, c-format
#| msgid "error reading `%s': %s\n"
msgid "error reading '%s': %s\n"
@@ -1360,17 +1367,9 @@ msgstr "viga võtmehoidlasse `%s' kirjutamisel: %s\n"
msgid "Login data (account name): "
msgstr ""
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr ""
-
msgid "Private DO data: "
msgstr ""
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy
msgid "Language preferences: "
msgstr "uuendatud eelistused"
@@ -1675,6 +1674,14 @@ msgstr ""
"sümmetrilise šifri %s (%d) kasutamine on vastuolus saaja eelistustega\n"
#, fuzzy, c-format
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "šifri algoritm \"%s\" ei ole moodis %s lubatud\n"
+
+#, fuzzy, c-format
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "HOIATUS: võtit \"%s\" ei soovitata kasutada.\n"
+
+#, fuzzy, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
"preferences\n"
@@ -1690,8 +1697,9 @@ msgstr ""
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s krüptitud kasutajale: \"%s\"\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "%s ei ole moodis %s lubatud.\n"
#, c-format
@@ -1872,6 +1880,10 @@ msgstr ""
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 "valid values for option '%s':\n"
+msgstr "vigased impordi võtmed\n"
+
#, fuzzy
msgid "make a signature"
msgstr "loo eraldiseisev allkiri"
@@ -2221,10 +2233,6 @@ msgid "show expiration dates during signature listings"
msgstr "Vastavat allkirja salajaste võtmete hoidlas pole\n"
#, fuzzy, c-format
-msgid "valid values for option '%s':\n"
-msgstr "vigased impordi võtmed\n"
-
-#, fuzzy, c-format
msgid "unknown TOFU policy '%s'\n"
msgstr "tundmatu vaikimisi saaja `%s'\n"
@@ -2232,10 +2240,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr ""
#, fuzzy, c-format
-msgid "invalid value for option '%s'\n"
-msgstr "vigased impordi võtmed\n"
-
-#, fuzzy, 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"
@@ -2380,9 +2384,6 @@ msgstr "kirjutan salajase võtme faili `%s'\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "valitud šifri algoritm ei ole lubatud\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "valitud lühendi algoritm ei ole lubatud\n"
-
#, fuzzy
msgid "selected compression algorithm is invalid\n"
msgstr "valitud šifri algoritm ei ole lubatud\n"
@@ -2431,15 +2432,11 @@ 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"
-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 "digest algorithm '%s' may not be used 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 "compression algorithm '%s' may not be used in %s mode\n"
msgstr "pakkimise algoritm \"%s\" ei ole moodis %s lubatud\n"
#, c-format
@@ -2458,14 +2455,14 @@ msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "%s ei ole moodis %s lubatud.\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "%s ei ole moodis %s lubatud.\n"
#, c-format
@@ -2596,6 +2593,10 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr ""
+#, fuzzy
+msgid "repair keys on import"
+msgstr "näita sõrmejälge"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "jätan bloki tüübiga %d vahele\n"
@@ -2983,59 +2984,6 @@ msgstr "[tühistamine]"
msgid "[self-signature]"
msgstr "[iseenda allkiri]"
-#, fuzzy, c-format
-msgid "error allocating memory: %s\n"
-msgstr "viga võtmehoidla `%s' loomisel: %s\n"
-
-#, fuzzy, c-format
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "võti %08lX: mittetoetatud avaliku võtme algoritm\n"
-
-#, fuzzy, c-format
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "%s allkiri, sõnumilühendi algoritm %s\n"
-
-#, fuzzy
-msgid " (reordered signatures follow)"
-msgstr "Korrektne allkiri kasutajalt \""
-
-#, fuzzy, c-format
-msgid "key %s:\n"
-msgstr "`%s' jätsin vahele: %s\n"
-
-#, fuzzy, c-format
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "Kasutaja ID \"%s\" on tühistatud."
-msgstr[1] "Kasutaja ID \"%s\" on tühistatud."
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "1 allkiri jäi testimata, kuna võti puudub\n"
-msgstr[1] "1 allkiri jäi testimata, kuna võti puudub\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d halba allkirja\n"
-msgstr[1] "%d halba allkirja\n"
-
-#, fuzzy, c-format
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "Korrektne allkiri kasutajalt \""
-msgstr[1] "Korrektne allkiri kasutajalt \""
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
#, fuzzy
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
@@ -3564,6 +3512,14 @@ msgstr "Võtmega %08lX pole midagi allkirjastada\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "%s ei ole lubatud kooditabel\n"
+#, fuzzy, c-format
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "viga: vigane sõrmejälg\n"
+
+#, fuzzy, c-format
+msgid "subkey \"%s\" not found\n"
+msgstr "võtit '%s' ei leitud: %s\n"
+
msgid "Digest: "
msgstr "Teatelühend: "
@@ -3896,6 +3852,10 @@ 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 "invalid value for option '%s'\n"
+msgstr "vigased impordi võtmed\n"
+
+#, fuzzy, c-format
msgid "preference '%s' duplicated\n"
msgstr "eelistus %c%lu on duplikaat\n"
@@ -4381,6 +4341,20 @@ msgstr[0] "%d halba allkirja\n"
msgstr[1] "%d halba allkirja\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d halba allkirja\n"
+msgstr[1] "%d halba allkirja\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "1 allkiri jäi testimata, kuna võti puudub\n"
+msgstr[1] "1 allkiri jäi testimata, kuna võti puudub\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4659,6 +4633,11 @@ msgstr "[ebakindel]"
msgid " aka \"%s\""
msgstr " ka \""
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr "HOIATUS: Seda võtit ei ole sertifitseeritud usaldatava allkirjaga!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "Allkiri aegus %s\n"
@@ -5213,6 +5192,10 @@ msgid "can't open signed data fd=%d: %s\n"
msgstr "allkirjastatud andmete avamine ebaõnnestus `%s'\n"
#, fuzzy, c-format
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "võti %08lX: kasutaja ID puudub\n"
+
+#, fuzzy, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "anonüümne saaja; proovin salajast võtit %08lX ...\n"
@@ -5392,6 +5375,11 @@ msgid "WARNING: signature digest conflict in message\n"
msgstr "HOIATUS: allkirja lühend on teatega konfliktne\n"
#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "%s ei ole moodis %s lubatud.\n"
+
+#, fuzzy, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr "HOIATUS: allkirjastamise alamvõti %08lX ei ole rist-sertifitseeritud\n"
@@ -8162,6 +8150,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr ""
#, fuzzy, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "viga `%s' lugemisel: %s\n"
+
+#, fuzzy, c-format
+msgid "error allocating memory: %s\n"
+msgstr "viga võtmehoidla `%s' loomisel: %s\n"
+
+#, fuzzy, c-format
msgid "error printing log line: %s\n"
msgstr "viga võtmehoidlasse `%s' kirjutamisel: %s\n"
@@ -8269,10 +8265,6 @@ msgid "error reading HTTP response for '%s': %s\n"
msgstr "viga `%s' lugemisel: %s\n"
#, fuzzy, c-format
-msgid "error accessing '%s': http status %u\n"
-msgstr "viga `%s' lugemisel: %s\n"
-
-#, fuzzy, c-format
msgid "error parsing OCSP response for '%s': %s\n"
msgstr "viga teate saatmisel serverile `%s': %s\n"
@@ -8890,6 +8882,36 @@ msgid ""
msgstr ""
#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "võti %08lX: mittetoetatud avaliku võtme algoritm\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "%s allkiri, sõnumilühendi algoritm %s\n"
+
+#, fuzzy
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "Korrektne allkiri kasutajalt \""
+
+#, fuzzy
+#~ msgid "key %s:\n"
+#~ msgstr "`%s' jätsin vahele: %s\n"
+
+#, fuzzy
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "Kasutaja ID \"%s\" on tühistatud."
+#~ msgstr[1] "Kasutaja ID \"%s\" on tühistatud."
+
+#, fuzzy
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "Korrektne allkiri kasutajalt \""
+#~ msgstr[1] "Korrektne allkiri kasutajalt \""
+
+#, fuzzy
#~| msgid "new configuration file `%s' created\n"
#~ msgid "new configuration file '%s' created\n"
#~ msgstr "uus omaduste fail `%s' on loodud\n"
diff --git a/po/fi.po b/po/fi.po
index ba6c056..6b145e4 100644
--- a/po/fi.po
+++ b/po/fi.po
@@ -407,6 +407,9 @@ msgstr ""
msgid "enable ssh support"
msgstr "ei tuettu"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable putty support"
@@ -433,6 +436,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr ""
+msgid "selected digest algorithm is invalid\n"
+msgstr "valittu tiivistealgoritmi ei kelpaa\n"
+
#, fuzzy, c-format
#| msgid "NOTE: no default option file `%s'\n"
msgid "Note: no default option file '%s'\n"
@@ -1296,6 +1302,11 @@ msgid "WARNING: %s\n"
msgstr "VAROITUS: %s korvaa %s:n\n"
#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s ja %s eivät vielä toimi yhdessä\n"
+
+#, fuzzy, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "salaista avainta ei löydy"
@@ -1363,10 +1374,6 @@ msgstr ""
msgid "URL to retrieve public key: "
msgstr "ei vastaavaa julkista avainta: %s\n"
-#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy, c-format
#| msgid "error reading `%s': %s\n"
msgid "error reading '%s': %s\n"
@@ -1379,17 +1386,9 @@ msgstr "virhe kirjoitettaessa avainrenkaaseen \"%s\": %s\n"
msgid "Login data (account name): "
msgstr ""
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr ""
-
msgid "Private DO data: "
msgstr ""
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy
msgid "Language preferences: "
msgstr "päivitä valinnat"
@@ -1693,6 +1692,14 @@ msgid ""
msgstr "valittu symmetrinen salain %s (%d) ei ole vastaanottajan suosima\n"
#, fuzzy, c-format
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "salausalgoritmia \"%s\" ei voi käyttää %s-tilassa\n"
+
+#, fuzzy, c-format
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "VAROITUS: \"%s\" on paheksuttu valitsin\n"
+
+#, fuzzy, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
"preferences\n"
@@ -1706,8 +1713,9 @@ msgstr "valittu symmetrinen salain %s (%d) ei ole vastaanottajan suosima\n"
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s salattu vastaanottajalle: \"%s\"\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "valitsinta %s ei voi käyttää %s-tilassa\n"
#, c-format
@@ -1887,6 +1895,10 @@ 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 "valid values for option '%s':\n"
+msgstr "virheelliset tuontivalitsimet\n"
+
#, fuzzy
msgid "make a signature"
msgstr "tee erillinen allekirjoitus"
@@ -2236,10 +2248,6 @@ msgid "show expiration dates during signature listings"
msgstr "Salaisesta avainrenkaasta ei löydy vastaavaa allekirjoitusta\n"
#, fuzzy, c-format
-msgid "valid values for option '%s':\n"
-msgstr "virheelliset tuontivalitsimet\n"
-
-#, fuzzy, c-format
msgid "unknown TOFU policy '%s'\n"
msgstr "tuntematon oletusvastaanottaja \"%s\"\n"
@@ -2247,10 +2255,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr ""
#, fuzzy, c-format
-msgid "invalid value for option '%s'\n"
-msgstr "virheelliset tuontivalitsimet\n"
-
-#, fuzzy, 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"
@@ -2395,9 +2399,6 @@ msgstr "kirjoitan salaisen avaimen kohteeseen \"%s\"\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "valittu salausalgoritmi ei kelpaa\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "valittu tiivistealgoritmi ei kelpaa\n"
-
#, fuzzy
msgid "selected compression algorithm is invalid\n"
msgstr "valittu salausalgoritmi ei kelpaa\n"
@@ -2447,15 +2448,11 @@ 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"
-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 "digest algorithm '%s' may not be used 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 "compression algorithm '%s' may not be used in %s mode\n"
msgstr "pakkausalgoritmia \"%s\" ei voi käyttää %s-tilassa\n"
#, c-format
@@ -2474,14 +2471,14 @@ msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "valitsinta %s ei voi käyttää %s-tilassa\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "valitsinta %s ei voi käyttää %s-tilassa\n"
#, c-format
@@ -2612,6 +2609,10 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr ""
+#, fuzzy
+msgid "repair keys on import"
+msgstr "näytä sormenjälki"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "ohitetaan tyypin %d lohko\n"
@@ -3002,60 +3003,6 @@ msgstr "[mitätöinti]"
msgid "[self-signature]"
msgstr "[oma-allekirjoitus]"
-#, fuzzy, c-format
-msgid "error allocating memory: %s\n"
-msgstr "virhe luotaessa avainrengasta \"%s\": %s\n"
-
-#, fuzzy, c-format
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "avain %08lX: julkisen avaimen algoritmia ei tueta\n"
-
-# Ensimmäinen %s on binary, textmode tai unknown, ks. alla
-#, fuzzy, c-format
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "%sallekirjoitus, tiivistealgoritmi %s\n"
-
-#, fuzzy
-msgid " (reordered signatures follow)"
-msgstr "Allekirjoitus täsmää lähettäjään \""
-
-#, fuzzy, c-format
-msgid "key %s:\n"
-msgstr "ohitetaan \"%s\": %s\n"
-
-#, fuzzy, c-format
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "Käyttäjätunnus \"%s\" on mitätöity."
-msgstr[1] "Käyttäjätunnus \"%s\" on mitätöity."
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "1 allekirjoitus jätetty tarkistamatta puuttuvan avaimen vuoksi\n"
-msgstr[1] "1 allekirjoitus jätetty tarkistamatta puuttuvan avaimen vuoksi\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d väärää allekirjoitusta\n"
-msgstr[1] "%d väärää allekirjoitusta\n"
-
-#, fuzzy, c-format
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "Allekirjoitus täsmää lähettäjään \""
-msgstr[1] "Allekirjoitus täsmää lähettäjään \""
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
#, fuzzy
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
@@ -3585,6 +3532,14 @@ msgstr "Avaimelle %08lX ei löydy mitään mitä allekirjoittaa\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "%s ei kelpaa merkistöksi\n"
+#, fuzzy, c-format
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "virhe: sormenjälki on väärä\n"
+
+#, fuzzy, c-format
+msgid "subkey \"%s\" not found\n"
+msgstr "avainta \"%s\" ei löydy: %s\n"
+
msgid "Digest: "
msgstr "Tiiviste: "
@@ -3922,6 +3877,10 @@ msgstr ""
"(käyttäjätunnus %d)\n"
#, fuzzy, c-format
+msgid "invalid value for option '%s'\n"
+msgstr "virheelliset tuontivalitsimet\n"
+
+#, fuzzy, c-format
msgid "preference '%s' duplicated\n"
msgstr "valinta %c%lu on kopio\n"
@@ -4412,6 +4371,20 @@ msgstr[0] "%d väärää allekirjoitusta\n"
msgstr[1] "%d väärää allekirjoitusta\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d väärää allekirjoitusta\n"
+msgstr[1] "%d väärää allekirjoitusta\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "1 allekirjoitus jätetty tarkistamatta puuttuvan avaimen vuoksi\n"
+msgstr[1] "1 allekirjoitus jätetty tarkistamatta puuttuvan avaimen vuoksi\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4693,6 +4666,12 @@ msgstr "[ei tiedossa]"
msgid " aka \"%s\""
msgstr " aka \""
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr ""
+"VAROITUS: Tätä avainta ei ole varmennettu luotettavalla allekirjoituksella!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "Allekirjoitus vanheni %s\n"
@@ -5261,6 +5240,10 @@ msgid "can't open signed data fd=%d: %s\n"
msgstr "allekirjoitetun datan \"%s\" avaaminen ei onnistu\n"
#, fuzzy, c-format
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "avain %08lX: ei käyttäjätunnusta\n"
+
+#, fuzzy, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "nimetön vastaanottaja; yritän käyttää salaista avainta %08lX ...\n"
@@ -5437,6 +5420,11 @@ msgid "WARNING: signature digest conflict in message\n"
msgstr "VAROITUS: allekirjoitustiiviste ei täsmää viestin kanssa\n"
#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "valitsinta %s ei voi käyttää %s-tilassa\n"
+
+#, fuzzy, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr "VAROITUS: allekirjoitusaliavain %08lX ei ole ristiinvarmennettu\n"
@@ -8224,6 +8212,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr ""
#, fuzzy, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "virhe luettaessa tiedostoa \"%s\": %s\n"
+
+#, fuzzy, c-format
+msgid "error allocating memory: %s\n"
+msgstr "virhe luotaessa avainrengasta \"%s\": %s\n"
+
+#, fuzzy, c-format
msgid "error printing log line: %s\n"
msgstr "virhe kirjoitettaessa avainrenkaaseen \"%s\": %s\n"
@@ -8331,10 +8327,6 @@ msgid "error reading HTTP response for '%s': %s\n"
msgstr "virhe luettaessa tiedostoa \"%s\": %s\n"
#, fuzzy, c-format
-msgid "error accessing '%s': http status %u\n"
-msgstr "virhe luettaessa tiedostoa \"%s\": %s\n"
-
-#, fuzzy, c-format
msgid "error parsing OCSP response for '%s': %s\n"
msgstr "virhe lähettäessä kohteeseen \"%s\": %s\n"
@@ -8952,6 +8944,37 @@ msgid ""
msgstr ""
#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "avain %08lX: julkisen avaimen algoritmia ei tueta\n"
+
+# Ensimmäinen %s on binary, textmode tai unknown, ks. alla
+#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "%sallekirjoitus, tiivistealgoritmi %s\n"
+
+#, fuzzy
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "Allekirjoitus täsmää lähettäjään \""
+
+#, fuzzy
+#~ msgid "key %s:\n"
+#~ msgstr "ohitetaan \"%s\": %s\n"
+
+#, fuzzy
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "Käyttäjätunnus \"%s\" on mitätöity."
+#~ msgstr[1] "Käyttäjätunnus \"%s\" on mitätöity."
+
+#, fuzzy
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "Allekirjoitus täsmää lähettäjään \""
+#~ msgstr[1] "Allekirjoitus täsmää lähettäjään \""
+
+#, fuzzy
#~| msgid "new configuration file `%s' created\n"
#~ msgid "new configuration file '%s' created\n"
#~ msgstr "uusi asetustiedosto \"%s\" luotu\n"
diff --git a/po/fr.po b/po/fr.po
index 77e03b7..375ccc8 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -397,6 +397,9 @@ msgstr ""
msgid "enable ssh support"
msgstr "activer la prise en charge de SSH"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
msgid "enable putty support"
msgstr "activer la prise en charge de putty"
@@ -423,6 +426,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr "niveau de débogage « %s » incorrect\n"
+msgid "selected digest algorithm is invalid\n"
+msgstr "la fonction de hachage sélectionnée est incorrecte\n"
+
#, c-format
msgid "Note: no default option file '%s'\n"
msgstr "Remarque : pas de fichier d'options par défaut « %s »\n"
@@ -1254,6 +1260,11 @@ msgstr ""
msgid "WARNING: %s\n"
msgstr "Attention : "
+#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s ne fonctionne pas encore avec %s\n"
+
#, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "la carte OpenPGP n'est pas disponible : %s\n"
@@ -1315,10 +1326,6 @@ msgid "URL to retrieve public key: "
msgstr "URL pour récupérer la clef publique : "
#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr "Erreur : URL trop longue (limitée à %d caractères).\n"
-
-#, c-format
msgid "error reading '%s': %s\n"
msgstr "erreur de lecture de « %s » : %s\n"
@@ -1329,19 +1336,9 @@ msgstr "erreur d'écriture de « %s » : %s\n"
msgid "Login data (account name): "
msgstr "Données d'identification (nom du compte) : "
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr ""
-"Erreur : données d'identification trop longues (limitées à\n"
-"%d caractères).\n"
-
msgid "Private DO data: "
msgstr "Données DO privées : "
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr "Erreur : DO privé trop long (limité à %d caractères).\n"
-
msgid "Language preferences: "
msgstr "Préférences de langue : "
@@ -1633,6 +1630,16 @@ msgstr ""
"Attention : forcer le chiffrement symétrique %s (%d) est en\n"
" désaccord avec les préférences du destinataire\n"
+#, fuzzy, c-format
+#| msgid "you may not use cipher algorithm '%s' while in %s mode\n"
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "impossible d'utiliser l'algorithme de chiffrement « %s » en mode %s.\n"
+
+#, fuzzy, c-format
+#| msgid "WARNING: \"%s%s\" is an obsolete option - it has no effect\n"
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "Attention : « %s%s » est une option obsolète — non prise en compte\n"
+
#, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
@@ -1651,8 +1658,9 @@ msgstr ""
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s chiffré pour : « %s »\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "impossible d'utiliser %s en mode %s.\n"
#, c-format
@@ -1826,6 +1834,11 @@ msgstr ""
"utilisation de la sous-clef %s à la place de la clef\n"
"principale %s\n"
+#, fuzzy, c-format
+#| msgid "invalid argument for option \"%.50s\"\n"
+msgid "valid values for option '%s':\n"
+msgstr "argument incorrect pour l'option « %.50s »\n"
+
msgid "make a signature"
msgstr "faire une signature"
@@ -2176,11 +2189,6 @@ msgid "show expiration dates during signature listings"
msgstr "montrer les dates d'expiration en affichant les signatures"
#, fuzzy, c-format
-#| msgid "invalid argument for option \"%.50s\"\n"
-msgid "valid values for option '%s':\n"
-msgstr "argument incorrect pour l'option « %.50s »\n"
-
-#, fuzzy, c-format
#| msgid "unknown option '%s'\n"
msgid "unknown TOFU policy '%s'\n"
msgstr "option « %s » inconnue\n"
@@ -2188,11 +2196,6 @@ msgstr "option « %s » inconnue\n"
msgid "(use \"help\" to list choices)\n"
msgstr ""
-#, fuzzy, c-format
-#| msgid "invalid argument for option \"%.50s\"\n"
-msgid "invalid value for option '%s'\n"
-msgstr "argument incorrect pour l'option « %.50s »\n"
-
#, c-format
msgid "Note: old default options file '%s' ignored\n"
msgstr "Remarque : l'ancien fichier d'options par défaut « %s » a été ignoré\n"
@@ -2333,9 +2336,6 @@ msgstr "ne sera pas exécuté avec une mémoire non sécurisée à cause de %s\n
msgid "selected cipher algorithm is invalid\n"
msgstr "l'algorithme de chiffrement sélectionné est incorrect\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "la fonction de hachage sélectionnée est incorrecte\n"
-
msgid "selected compression algorithm is invalid\n"
msgstr "l'algorithme de compression sélectionné est incorrect\n"
@@ -2379,16 +2379,14 @@ msgstr "préférences personnelles de compression incorrectes\n"
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"
-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"
+#, fuzzy, c-format
+#| msgid "you may not use digest algorithm '%s' while in %s mode\n"
+msgid "digest algorithm '%s' may not be used 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"
+#, fuzzy, c-format
+#| msgid "you may not use compression algorithm '%s' while in %s mode\n"
+msgid "compression algorithm '%s' may not be used in %s mode\n"
msgstr "impossible d'utiliser l'algorithme de compression « %s » en mode %s.\n"
#, c-format
@@ -2407,15 +2405,17 @@ msgstr "échec du chiffrement symétrique de « %s » : %s\n"
msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr "impossible d'utiliser --symmetric --encrypt avec --s2k-mode 0\n"
-#, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "impossible d'utiliser --symmetric --encrypt en mode %s\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr "impossible d'utiliser --symmetric --sign --encrypt avec --s2k-mode 0\n"
-#, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "impossible d'utiliser --symmetric --sign --encrypt en mode %s\n"
#, c-format
@@ -2544,6 +2544,11 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr "entrée supposée au format binaire"
+#, fuzzy
+#| msgid "show key fingerprint"
+msgid "repair keys on import"
+msgstr "afficher l'empreinte de la clef"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "un bloc de type %d a été ignoré\n"
@@ -2933,65 +2938,6 @@ msgstr "[révocation]"
msgid "[self-signature]"
msgstr "[autosignature]"
-#, c-format
-msgid "error allocating memory: %s\n"
-msgstr "erreur d'allocation de mémoire : %s\n"
-
-#, fuzzy, c-format
-#| msgid "key %s: unsupported public key algorithm\n"
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "clef %s : algorithme à clef publique non pris en charge\n"
-
-#, fuzzy, c-format
-#| msgid "card does not support digest algorithm %s\n"
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "la carte ne gère pas l'algorithme de hachage %s\n"
-
-#, fuzzy
-#| msgid "Good signature from"
-msgid " (reordered signatures follow)"
-msgstr "Bonne signature de"
-
-#, fuzzy, c-format
-#| msgid "key %s: %s\n"
-msgid "key %s:\n"
-msgstr "clef %s : %s\n"
-
-#, fuzzy, c-format
-#| msgid "User ID \"%s\": %d signature removed\n"
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "Identité « %s » : %d signature supprimée\n"
-msgstr[1] "Identité « %s » : %d signature supprimée\n"
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "1 signature non vérifiée à cause d'une clef manquante\n"
-msgstr[1] "1 signature non vérifiée à cause d'une clef manquante\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d mauvaises signatures\n"
-msgstr[1] "%d mauvaises signatures\n"
-
-#, fuzzy, c-format
-#| msgid "Good signature from"
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "Bonne signature de"
-msgstr[1] "Bonne signature de"
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
"keys\n"
@@ -3478,6 +3424,16 @@ msgstr "Rien à signer.\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "« %s » n'est pas une date d'expiration de signature valable\n"
+#, fuzzy, c-format
+#| msgid "\"%s\" is not a fingerprint\n"
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "« %s » n’est pas une empreinte\n"
+
+#, fuzzy, c-format
+#| msgid "key \"%s\" not found: %s\n"
+msgid "subkey \"%s\" not found\n"
+msgstr "clef « %s » introuvable : %s\n"
+
msgid "Digest: "
msgstr "Hachage : "
@@ -3811,6 +3767,11 @@ msgstr ""
"Affichage de la photo d'identité %s de taille %ld pour la clef\n"
"%s (uid %d)\n"
+#, fuzzy, c-format
+#| msgid "invalid argument for option \"%.50s\"\n"
+msgid "invalid value for option '%s'\n"
+msgstr "argument incorrect pour l'option « %.50s »\n"
+
#, c-format
msgid "preference '%s' duplicated\n"
msgstr "préférence « %s » en double\n"
@@ -4294,6 +4255,20 @@ msgstr[0] "%d mauvaises signatures\n"
msgstr[1] "%d mauvaises signatures\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d mauvaises signatures\n"
+msgstr[1] "%d mauvaises signatures\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "1 signature non vérifiée à cause d'une clef manquante\n"
+msgstr[1] "1 signature non vérifiée à cause d'une clef manquante\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4576,6 +4551,12 @@ msgstr "[doute]"
msgid " aka \"%s\""
msgstr " alias « %s »"
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr ""
+"Attention : cette clef n'est pas certifiée avec une signature de confiance.\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "La signature a expiré le %s\n"
@@ -5153,6 +5134,11 @@ msgstr "impossible d'ouvrir les données signées « %s »\n"
msgid "can't open signed data fd=%d: %s\n"
msgstr "impossible d'ouvrir les données signées fd=%d : %s\n"
+#, fuzzy, c-format
+#| msgid "certificate is not usable for encryption\n"
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "le certificat n'est pas utilisable pour le chiffrement\n"
+
#, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "destinataire anonyme ; essai avec clef secrète %s…\n"
@@ -5350,6 +5336,11 @@ msgstr ""
msgid "WARNING: signature digest conflict in message\n"
msgstr "Attention : conflit de hachage de signature dans le message\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "impossible d'utiliser %s en mode %s.\n"
+
#, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr ""
@@ -8194,6 +8185,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr "« %s » est une URL LDAP incorrecte\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 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"
@@ -8300,10 +8299,6 @@ 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"
@@ -8924,6 +8919,53 @@ msgstr ""
"Vérifier une phrase secrète donnée sur l'entrée standard par rapport à "
"ficmotif\n"
+#~ msgid "Error: URL too long (limit is %d characters).\n"
+#~ msgstr "Erreur : URL trop longue (limitée à %d caractères).\n"
+
+#~ msgid "Error: Login data too long (limit is %d characters).\n"
+#~ msgstr ""
+#~ "Erreur : données d'identification trop longues (limitées à\n"
+#~ "%d caractères).\n"
+
+#~ msgid "Error: Private DO too long (limit is %d characters).\n"
+#~ msgstr "Erreur : DO privé trop long (limité à %d caractères).\n"
+
+#, fuzzy
+#~| msgid "key %s: unsupported public key algorithm\n"
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "clef %s : algorithme à clef publique non pris en charge\n"
+
+#, fuzzy
+#~| msgid "card does not support digest algorithm %s\n"
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "la carte ne gère pas l'algorithme de hachage %s\n"
+
+#, fuzzy
+#~| msgid "Good signature from"
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "Bonne signature de"
+
+#, fuzzy
+#~| msgid "key %s: %s\n"
+#~ msgid "key %s:\n"
+#~ msgstr "clef %s : %s\n"
+
+#, fuzzy
+#~| msgid "User ID \"%s\": %d signature removed\n"
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "Identité « %s » : %d signature supprimée\n"
+#~ msgstr[1] "Identité « %s » : %d signature supprimée\n"
+
+#, fuzzy
+#~| msgid "Good signature from"
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "Bonne signature de"
+#~ msgstr[1] "Bonne signature de"
+
#~ msgid "new configuration file '%s' created\n"
#~ msgstr "nouveau fichier de configuration « %s » créé\n"
diff --git a/po/gl.po b/po/gl.po
index 35559b3..6f2790e 100644
--- a/po/gl.po
+++ b/po/gl.po
@@ -393,6 +393,9 @@ msgstr ""
msgid "enable ssh support"
msgstr "non está soportado"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable putty support"
@@ -420,6 +423,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr ""
+msgid "selected digest algorithm is invalid\n"
+msgstr "o algoritmo de resumo seleccionado non é válido\n"
+
#, fuzzy, c-format
#| msgid "NOTE: no default option file `%s'\n"
msgid "Note: no default option file '%s'\n"
@@ -1286,6 +1292,11 @@ msgid "WARNING: %s\n"
msgstr "AVISO: %s fai que se ignore %s\n"
#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "¡%s aínda non traballa con %s!\n"
+
+#, fuzzy, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "a chave secreta non está dispoñible"
@@ -1353,10 +1364,6 @@ msgstr ""
msgid "URL to retrieve public key: "
msgstr "non hai unha chave pública correspondente: %s\n"
-#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy, c-format
#| msgid "error reading `%s': %s\n"
msgid "error reading '%s': %s\n"
@@ -1369,17 +1376,9 @@ msgstr "erro escribindo no chaveiro `%s': %s\n"
msgid "Login data (account name): "
msgstr ""
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr ""
-
msgid "Private DO data: "
msgstr ""
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy
msgid "Language preferences: "
msgstr "preferencias actualizadas"
@@ -1685,6 +1684,14 @@ msgstr ""
"forza-la cifra simétrica %s (%d) viola as preferencias do destinatario\n"
#, fuzzy, c-format
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "non se pode empregar o algoritmo de cifrado \"%s\" no modo %s\n"
+
+#, fuzzy, c-format
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "AVISO: \"%s\" é unha opción a extinguir\n"
+
+#, fuzzy, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
"preferences\n"
@@ -1701,8 +1708,9 @@ msgstr ""
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s cifrado para: \"%s\"\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "non se pode empregar %s no modo %s\n"
#, c-format
@@ -1880,6 +1888,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 "valid values for option '%s':\n"
+msgstr "opcións de importación non válidas\n"
+
#, fuzzy
msgid "make a signature"
msgstr "facer unha sinatura separada"
@@ -2229,10 +2241,6 @@ msgid "show expiration dates during signature listings"
msgstr "Non hai unha sinatura correspondiente no chaveiro secreto\n"
#, fuzzy, c-format
-msgid "valid values for option '%s':\n"
-msgstr "opcións de importación non válidas\n"
-
-#, fuzzy, c-format
msgid "unknown TOFU policy '%s'\n"
msgstr "destinatario por defecto `%s' descoñecido\n"
@@ -2240,10 +2248,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr ""
#, fuzzy, c-format
-msgid "invalid value for option '%s'\n"
-msgstr "opcións de importación non válidas\n"
-
-#, fuzzy, 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"
@@ -2388,9 +2392,6 @@ msgstr "gravando a chave secreta en `%s'\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "o algoritmo de cifrado seleccionado non é válido\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "o algoritmo de resumo seleccionado non é válido\n"
-
#, fuzzy
msgid "selected compression algorithm is invalid\n"
msgstr "o algoritmo de cifrado seleccionado non é válido\n"
@@ -2441,15 +2442,11 @@ 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"
-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 "digest algorithm '%s' may not be used 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 "compression algorithm '%s' may not be used in %s mode\n"
msgstr "non se pode empregar o algoritmo de compresión \"%s\" no modo %s\n"
#, c-format
@@ -2468,14 +2465,14 @@ msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "non se pode empregar %s no modo %s\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "non se pode empregar %s no modo %s\n"
#, c-format
@@ -2606,6 +2603,10 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr ""
+#, fuzzy
+msgid "repair keys on import"
+msgstr "amosar fingerprint"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "pasando por alto un bloque de tipo %d\n"
@@ -3004,59 +3005,6 @@ msgstr "[revocación]"
msgid "[self-signature]"
msgstr "[auto-sinatura]"
-#, fuzzy, c-format
-msgid "error allocating memory: %s\n"
-msgstr "erro ao crea-lo chaveiro `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "chave %08lX: algoritmo de chave pública non soportado\n"
-
-#, fuzzy, c-format
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "Sinatura %s, algoritmo de resumo %s\n"
-
-#, fuzzy
-msgid " (reordered signatures follow)"
-msgstr "Sinatura correcta de \""
-
-#, fuzzy, c-format
-msgid "key %s:\n"
-msgstr "omítese `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "O ID de usuario \"%s\" está revocado."
-msgstr[1] "O ID de usuario \"%s\" está revocado."
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "1 sinatura non verificada debido a unha chave que falta\n"
-msgstr[1] "1 sinatura non verificada debido a unha chave que falta\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d sinaturas erróneas\n"
-msgstr[1] "%d sinaturas erróneas\n"
-
-#, fuzzy, c-format
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "Sinatura correcta de \""
-msgstr[1] "Sinatura correcta de \""
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
#, fuzzy
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
@@ -3590,6 +3538,14 @@ msgstr "Nada que asinar coa chave %08lX\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "%s non é un xogo de caracteres válido\n"
+#, fuzzy, c-format
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "erro: pegada dactilar non válida\n"
+
+#, fuzzy, c-format
+msgid "subkey \"%s\" not found\n"
+msgstr "non se atopou a chave `%s': %s\n"
+
msgid "Digest: "
msgstr "Resumo: "
@@ -3933,6 +3889,10 @@ msgstr ""
"Amosando a id. fotográfica %s de tamaño %ld da chave 0x%08lX (uid %d)\n"
#, fuzzy, c-format
+msgid "invalid value for option '%s'\n"
+msgstr "opcións de importación non válidas\n"
+
+#, fuzzy, c-format
msgid "preference '%s' duplicated\n"
msgstr "preferencia %c%lu duplicada\n"
@@ -4426,6 +4386,20 @@ msgstr[0] "%d sinaturas erróneas\n"
msgstr[1] "%d sinaturas erróneas\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d sinaturas erróneas\n"
+msgstr[1] "%d sinaturas erróneas\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "1 sinatura non verificada debido a unha chave que falta\n"
+msgstr[1] "1 sinatura non verificada debido a unha chave que falta\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4706,6 +4680,11 @@ msgstr "[incerto]"
msgid " aka \"%s\""
msgstr " alias \""
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr "AVISO: ¡Esta chave non está certificada cunha sinatura de confianza!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "A sinatura caducou o %s\n"
@@ -5272,6 +5251,10 @@ msgid "can't open signed data fd=%d: %s\n"
msgstr "non foi posible abri-los datos asinados `%s'\n"
#, fuzzy, c-format
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "chave %08lX: non hai ID de usuario\n"
+
+#, fuzzy, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "destinatario anónimo; tentando a chave secreta %08lX ...\n"
@@ -5445,6 +5428,11 @@ msgstr ""
msgid "WARNING: signature digest conflict in message\n"
msgstr "AVISO: conflicto de resumo de sinatura na mensaxe\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "non se pode empregar %s no modo %s\n"
+
#, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr ""
@@ -8250,6 +8238,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr ""
#, fuzzy, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "erro lendo `%s': %s\n"
+
+#, fuzzy, c-format
+msgid "error allocating memory: %s\n"
+msgstr "erro ao crea-lo chaveiro `%s': %s\n"
+
+#, fuzzy, c-format
msgid "error printing log line: %s\n"
msgstr "erro escribindo no chaveiro `%s': %s\n"
@@ -8357,10 +8353,6 @@ msgid "error reading HTTP response for '%s': %s\n"
msgstr "erro lendo `%s': %s\n"
#, fuzzy, c-format
-msgid "error accessing '%s': http status %u\n"
-msgstr "erro lendo `%s': %s\n"
-
-#, fuzzy, c-format
msgid "error parsing OCSP response for '%s': %s\n"
msgstr "erro ao enviar a `%s': %s\n"
@@ -8981,6 +8973,36 @@ msgid ""
msgstr ""
#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "chave %08lX: algoritmo de chave pública non soportado\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "Sinatura %s, algoritmo de resumo %s\n"
+
+#, fuzzy
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "Sinatura correcta de \""
+
+#, fuzzy
+#~ msgid "key %s:\n"
+#~ msgstr "omítese `%s': %s\n"
+
+#, fuzzy
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "O ID de usuario \"%s\" está revocado."
+#~ msgstr[1] "O ID de usuario \"%s\" está revocado."
+
+#, fuzzy
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "Sinatura correcta de \""
+#~ msgstr[1] "Sinatura correcta de \""
+
+#, fuzzy
#~| msgid "new configuration file `%s' created\n"
#~ msgid "new configuration file '%s' created\n"
#~ msgstr " creouse un novo ficheiro de configuración `%s'\n"
diff --git a/po/hu.po b/po/hu.po
index 828f66c..fcdc9b7 100644
--- a/po/hu.po
+++ b/po/hu.po
@@ -391,6 +391,9 @@ msgstr ""
msgid "enable ssh support"
msgstr "nem támogatott"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable putty support"
@@ -416,6 +419,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr ""
+msgid "selected digest algorithm is invalid\n"
+msgstr "A kiválasztott kivonatoló algoritmus érvénytelen!\n"
+
#, fuzzy, c-format
#| msgid "NOTE: no default option file `%s'\n"
msgid "Note: no default option file '%s'\n"
@@ -1277,6 +1283,11 @@ msgid "WARNING: %s\n"
msgstr "FIGYELEM: %s hatástalanítja %s-t!\n"
#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s és %s egyelőre nem használható együtt!\n"
+
+#, fuzzy, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "titkos kulcs nem áll rendelkezésre"
@@ -1344,10 +1355,6 @@ msgstr ""
msgid "URL to retrieve public key: "
msgstr "Nincs hozzá tartozó nyilvános kulcs: %s\n"
-#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy, c-format
#| msgid "error reading `%s': %s\n"
msgid "error reading '%s': %s\n"
@@ -1360,17 +1367,9 @@ msgstr "Hiba a \"%s\" kulcskarika írásakor: %s\n"
msgid "Login data (account name): "
msgstr ""
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr ""
-
msgid "Private DO data: "
msgstr ""
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy
msgid "Language preferences: "
msgstr "preferenciák frissítése"
@@ -1674,6 +1673,15 @@ msgid ""
msgstr "A %s (%d) rejtjelező használata sérti a címzett preferenciáit!\n"
#, fuzzy, c-format
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr ""
+"Lehet, hogy nem használhatja \"%s\" rejtjelező algoritmust %s módban!\n"
+
+#, fuzzy, c-format
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "FIGYELEM: \"%s\" elavult opció!\n"
+
+#, fuzzy, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
"preferences\n"
@@ -1687,8 +1695,9 @@ msgstr "A %s (%d) rejtjelező használata sérti a címzett preferenciáit!\n"
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s titkosítva \"%s\" számára\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "Lehet, hogy nem használhatja %s-t %s módban!\n"
#, c-format
@@ -1868,6 +1877,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 "valid values for option '%s':\n"
+msgstr "Érvénytelen import opciók!\n"
+
#, fuzzy
msgid "make a signature"
msgstr "különálló aláírás készítése"
@@ -2217,10 +2230,6 @@ msgid "show expiration dates during signature listings"
msgstr "Nincs megfelelő aláírás a titkoskulcs-karikán.\n"
#, fuzzy, c-format
-msgid "valid values for option '%s':\n"
-msgstr "Érvénytelen import opciók!\n"
-
-#, fuzzy, c-format
msgid "unknown TOFU policy '%s'\n"
msgstr "Ismeretlen alapértelmezett címzett: \"%s\"\n"
@@ -2228,10 +2237,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr ""
#, fuzzy, c-format
-msgid "invalid value for option '%s'\n"
-msgstr "Érvénytelen import opciók!\n"
-
-#, fuzzy, 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"
@@ -2376,9 +2381,6 @@ msgstr "Írom a titkos kulcsot a %s állományba.\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "A kiválasztott rejtjelező algoritmus érvénytelen!\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "A kiválasztott kivonatoló algoritmus érvénytelen!\n"
-
#, fuzzy
msgid "selected compression algorithm is invalid\n"
msgstr "A kiválasztott rejtjelező algoritmus érvénytelen!\n"
@@ -2427,17 +2429,12 @@ 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"
-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 "digest algorithm '%s' may not be used 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 "compression algorithm '%s' may not be used in %s mode\n"
msgstr "Lehet, hogy nem használhatja \"%s\" tömörítő algoritmust %s módban!\n"
#, c-format
@@ -2456,14 +2453,14 @@ msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "Lehet, hogy nem használhatja %s-t %s módban!\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "Lehet, hogy nem használhatja %s-t %s módban!\n"
#, c-format
@@ -2594,6 +2591,10 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr ""
+#, fuzzy
+msgid "repair keys on import"
+msgstr "megmutatja az ujjlenyomatot"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "%d típusú blokkot kihagyom.\n"
@@ -2984,59 +2985,6 @@ msgstr "[visszavonás]"
msgid "[self-signature]"
msgstr "[önaláírás]"
-#, fuzzy, c-format
-msgid "error allocating memory: %s\n"
-msgstr "Hiba a(z) \"%s\" kulcskarika létrehozásakor: %s\n"
-
-#, fuzzy, c-format
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "%08lX kulcs: Nem támogatott nyilvános kulcsú algoritmus!\n"
-
-#, fuzzy, c-format
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "%s aláírás, %s kivonatoló algoritmus.\n"
-
-#, fuzzy
-msgid " (reordered signatures follow)"
-msgstr "Jó aláírás a következőtől: \""
-
-#, fuzzy, c-format
-msgid "key %s:\n"
-msgstr "Kihagytam \"%s\"-t: %s.\n"
-
-#, fuzzy, c-format
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "\"%s\" felhasználói azonosítót visszavonták."
-msgstr[1] "\"%s\" felhasználói azonosítót visszavonták."
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "1 aláírást nem ellenőriztem hiányzó kulcs miatt.\n"
-msgstr[1] "1 aláírást nem ellenőriztem hiányzó kulcs miatt.\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d rossz aláírás.\n"
-msgstr[1] "%d rossz aláírás.\n"
-
-#, fuzzy, c-format
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "Jó aláírás a következőtől: \""
-msgstr[1] "Jó aláírás a következőtől: \""
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
#, fuzzy
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
@@ -3563,6 +3511,14 @@ msgstr "Nincs mit aláírni a %08lX kulccsal!\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "%s nem érvényes karakterkiosztás!\n"
+#, fuzzy, c-format
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "Hiba: Érvénytelen ujjlenyomat.\n"
+
+#, fuzzy, c-format
+msgid "subkey \"%s\" not found\n"
+msgstr "\"%s\" kulcs nem található: %s\n"
+
msgid "Digest: "
msgstr "Kivonat: "
@@ -3898,6 +3854,10 @@ 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 "invalid value for option '%s'\n"
+msgstr "Érvénytelen import opciók!\n"
+
+#, fuzzy, c-format
msgid "preference '%s' duplicated\n"
msgstr "%c%lu preferencia kétszer szerepel!\n"
@@ -4391,6 +4351,20 @@ msgstr[0] "%d rossz aláírás.\n"
msgstr[1] "%d rossz aláírás.\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d rossz aláírás.\n"
+msgstr[1] "%d rossz aláírás.\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "1 aláírást nem ellenőriztem hiányzó kulcs miatt.\n"
+msgstr[1] "1 aláírást nem ellenőriztem hiányzó kulcs miatt.\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4674,6 +4648,11 @@ msgstr "[bizonytalan]"
msgid " aka \"%s\""
msgstr " azaz \""
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr "FIGYELEM: Ez a kulcs nincs hitelesítve megbízható aláírással!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "Az aláírás lejárt: %s.\n"
@@ -5236,6 +5215,10 @@ msgid "can't open signed data fd=%d: %s\n"
msgstr "Nem tudom megnyitni a(z) \"%s\" aláírt adatot!\n"
#, fuzzy, c-format
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "%08lX kulcs: Nincs felhasználói azonosító.\n"
+
+#, fuzzy, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "Anonim címzett. A %08lX titkos kulcsot próbálom...\n"
@@ -5410,6 +5393,11 @@ msgid "WARNING: signature digest conflict in message\n"
msgstr "FIGYELEM: Aláíráskivonat-konfliktus az üzenetben.\n"
#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "Lehet, hogy nem használhatja %s-t %s módban!\n"
+
+#, fuzzy, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr "FIGYELEM: %08lX aláíró alkulcs nem kereszthitelesített.\n"
@@ -8192,6 +8180,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr ""
#, fuzzy, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "Hiba \"%s\" olvasásakor: %s\n"
+
+#, fuzzy, c-format
+msgid "error allocating memory: %s\n"
+msgstr "Hiba a(z) \"%s\" kulcskarika létrehozásakor: %s\n"
+
+#, fuzzy, c-format
msgid "error printing log line: %s\n"
msgstr "Hiba a \"%s\" kulcskarika írásakor: %s\n"
@@ -8299,10 +8295,6 @@ msgid "error reading HTTP response for '%s': %s\n"
msgstr "Hiba \"%s\" olvasásakor: %s\n"
#, fuzzy, c-format
-msgid "error accessing '%s': http status %u\n"
-msgstr "Hiba \"%s\" olvasásakor: %s\n"
-
-#, fuzzy, c-format
msgid "error parsing OCSP response for '%s': %s\n"
msgstr "Hiba %s-ra/-re küldéskor: %s\n"
@@ -8920,6 +8912,36 @@ msgid ""
msgstr ""
#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "%08lX kulcs: Nem támogatott nyilvános kulcsú algoritmus!\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "%s aláírás, %s kivonatoló algoritmus.\n"
+
+#, fuzzy
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "Jó aláírás a következőtől: \""
+
+#, fuzzy
+#~ msgid "key %s:\n"
+#~ msgstr "Kihagytam \"%s\"-t: %s.\n"
+
+#, fuzzy
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "\"%s\" felhasználói azonosítót visszavonták."
+#~ msgstr[1] "\"%s\" felhasználói azonosítót visszavonták."
+
+#, fuzzy
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "Jó aláírás a következőtől: \""
+#~ msgstr[1] "Jó aláírás a következőtől: \""
+
+#, fuzzy
#~| 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"
diff --git a/po/id.po b/po/id.po
index c2a698f..cf0f261 100644
--- a/po/id.po
+++ b/po/id.po
@@ -396,6 +396,9 @@ msgstr ""
msgid "enable ssh support"
msgstr "tidak didukung"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable putty support"
@@ -421,6 +424,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr ""
+msgid "selected digest algorithm is invalid\n"
+msgstr "algoritma digest yang dipilih tidak valid\n"
+
#, fuzzy, c-format
#| msgid "NOTE: no default option file `%s'\n"
msgid "Note: no default option file '%s'\n"
@@ -1283,6 +1289,11 @@ msgid "WARNING: %s\n"
msgstr "PERINGATAN: %s menimpa %s\n"
#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s belum dapat dipakai dengan %s\n"
+
+#, fuzzy, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "kunci rahasia tidak tersedia"
@@ -1350,10 +1361,6 @@ msgstr ""
msgid "URL to retrieve public key: "
msgstr "tidak ada kunci publik yang sesuai: %s\n"
-#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy, c-format
#| msgid "error reading `%s': %s\n"
msgid "error reading '%s': %s\n"
@@ -1366,17 +1373,9 @@ msgstr "kesalahan menulis keyring `%s': %s\n"
msgid "Login data (account name): "
msgstr ""
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr ""
-
msgid "Private DO data: "
msgstr ""
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy
msgid "Language preferences: "
msgstr "perbarui preferensi"
@@ -1680,6 +1679,15 @@ msgid ""
msgstr "memaksa cipher simetrik %s (%d) melanggar preferensi penerima\n"
#, fuzzy, c-format
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr ""
+"anda tidak boleh menggunakan algoritma cipher \"%s\" saat dalam mode %s.\n"
+
+#, fuzzy, c-format
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "WARNING: \"%s\" adalah opsi terdepresiasi\n"
+
+#, fuzzy, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
"preferences\n"
@@ -1693,8 +1701,9 @@ msgstr "memaksa cipher simetrik %s (%d) melanggar preferensi penerima\n"
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s dienkripsi untuk: %s\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "anda tidak boleh menggunakan %s saat dalam mode %s.\n"
#, c-format
@@ -1871,6 +1880,10 @@ msgstr "kunci tidak valid %08lX dibuat valid oleh --allow-non-selfsigned-uid\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 "valid values for option '%s':\n"
+msgstr "opsi impor tidak valid\n"
+
#, fuzzy
msgid "make a signature"
msgstr "buat detached signature"
@@ -2220,10 +2233,6 @@ msgid "show expiration dates during signature listings"
msgstr "Tidak ada signature koresponden di ring rahasia\n"
#, fuzzy, c-format
-msgid "valid values for option '%s':\n"
-msgstr "opsi impor tidak valid\n"
-
-#, fuzzy, c-format
msgid "unknown TOFU policy '%s'\n"
msgstr "penerima baku tidak dikenal `%s'\n"
@@ -2231,10 +2240,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr ""
#, fuzzy, c-format
-msgid "invalid value for option '%s'\n"
-msgstr "opsi impor tidak valid\n"
-
-#, fuzzy, 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"
@@ -2379,9 +2384,6 @@ msgstr "menulis kunci rahasia ke `%s'\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "algoritma cipher yang dipilih tidak valid\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "algoritma digest yang dipilih tidak valid\n"
-
#, fuzzy
msgid "selected compression algorithm is invalid\n"
msgstr "algoritma cipher yang dipilih tidak valid\n"
@@ -2430,17 +2432,12 @@ 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"
-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 "digest algorithm '%s' may not be used 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 "compression algorithm '%s' may not be used in %s mode\n"
msgstr ""
"anda tidak boleh menggunakan algoritma kompresi \"%s\" saat dalam mode %s.\n"
@@ -2461,14 +2458,14 @@ msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "anda tidak boleh menggunakan %s saat dalam mode %s.\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "anda tidak boleh menggunakan %s saat dalam mode %s.\n"
#, c-format
@@ -2599,6 +2596,10 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr ""
+#, fuzzy
+msgid "repair keys on import"
+msgstr "tampilkan fingerprint"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "melewati blok tipe %d\n"
@@ -2986,59 +2987,6 @@ msgstr "[pembatalan]"
msgid "[self-signature]"
msgstr "[self-signature]"
-#, fuzzy, c-format
-msgid "error allocating memory: %s\n"
-msgstr "kesalahan menulis keyring `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "kunci %08lX: algoritma publik key tidak didukung\n"
-
-#, fuzzy, c-format
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "%s signature, algoritma digest %s\n"
-
-#, fuzzy
-msgid " (reordered signatures follow)"
-msgstr "Signature baik dari \""
-
-#, fuzzy, c-format
-msgid "key %s:\n"
-msgstr "melewati `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "User ID \"%s\" dibatalkan."
-msgstr[1] "User ID \"%s\" dibatalkan."
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "1 signature tidak diperiksa karena tidak ada kunci\n"
-msgstr[1] "1 signature tidak diperiksa karena tidak ada kunci\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d signature yang buruk\n"
-msgstr[1] "%d signature yang buruk\n"
-
-#, fuzzy, c-format
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "Signature baik dari \""
-msgstr[1] "Signature baik dari \""
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
#, fuzzy
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
@@ -3568,6 +3516,14 @@ msgstr "Tidak ada yang ditandai dengan kunci %08lX\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "%s bukanlah set karakter yang valid\n"
+#, fuzzy, c-format
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "kesalahan: fingerprint tidak valid\n"
+
+#, fuzzy, c-format
+msgid "subkey \"%s\" not found\n"
+msgstr "kunci '%s' tidak ditemukan: %s\n"
+
msgid "Digest: "
msgstr "Digest: "
@@ -3907,6 +3863,10 @@ 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 "invalid value for option '%s'\n"
+msgstr "opsi impor tidak valid\n"
+
+#, fuzzy, c-format
msgid "preference '%s' duplicated\n"
msgstr "preferensi %c%lu ganda \n"
@@ -4395,6 +4355,20 @@ msgstr[0] "%d signature yang buruk\n"
msgstr[1] "%d signature yang buruk\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d signature yang buruk\n"
+msgstr[1] "%d signature yang buruk\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "1 signature tidak diperiksa karena tidak ada kunci\n"
+msgstr[1] "1 signature tidak diperiksa karena tidak ada kunci\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4673,6 +4647,12 @@ msgstr "[uncertain]"
msgid " aka \"%s\""
msgstr " alias \""
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr ""
+"PERINGATAN: Kunci ini tidak disertifikasi dengan sig yang terpercaya!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "Signature kadaluwarsa %s\n"
@@ -5229,6 +5209,10 @@ msgid "can't open signed data fd=%d: %s\n"
msgstr "tidak dapat membuka data tertandai `%s'\n"
#, fuzzy, c-format
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "kunci %08lX: tidak ada ID user\n"
+
+#, fuzzy, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "penerima anonim; mencoba kunci rahasia %08lX ...\n"
@@ -5405,6 +5389,11 @@ msgid "WARNING: signature digest conflict in message\n"
msgstr "Peringatan: konflik digest signature dalam pesan\n"
#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "anda tidak boleh menggunakan %s saat dalam mode %s.\n"
+
+#, fuzzy, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr "PERINGATAN: subkey penandatangan %08lX tidak tersertifikasi silang\n"
@@ -8184,6 +8173,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr ""
#, fuzzy, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "kesalahan membaca `%s': %s\n"
+
+#, fuzzy, c-format
+msgid "error allocating memory: %s\n"
+msgstr "kesalahan menulis keyring `%s': %s\n"
+
+#, fuzzy, c-format
msgid "error printing log line: %s\n"
msgstr "kesalahan menulis keyring `%s': %s\n"
@@ -8291,10 +8288,6 @@ msgid "error reading HTTP response for '%s': %s\n"
msgstr "kesalahan membaca `%s': %s\n"
#, fuzzy, c-format
-msgid "error accessing '%s': http status %u\n"
-msgstr "kesalahan membaca `%s': %s\n"
-
-#, fuzzy, c-format
msgid "error parsing OCSP response for '%s': %s\n"
msgstr "kesalahan mengirim ke `%s': %s\n"
@@ -8912,6 +8905,36 @@ msgid ""
msgstr ""
#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "kunci %08lX: algoritma publik key tidak didukung\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "%s signature, algoritma digest %s\n"
+
+#, fuzzy
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "Signature baik dari \""
+
+#, fuzzy
+#~ msgid "key %s:\n"
+#~ msgstr "melewati `%s': %s\n"
+
+#, fuzzy
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "User ID \"%s\" dibatalkan."
+#~ msgstr[1] "User ID \"%s\" dibatalkan."
+
+#, fuzzy
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "Signature baik dari \""
+#~ msgstr[1] "Signature baik dari \""
+
+#, fuzzy
#~| msgid "new configuration file `%s' created\n"
#~ msgid "new configuration file '%s' created\n"
#~ msgstr "file konfigurasi baru `%s' tercipta\n"
diff --git a/po/it.po b/po/it.po
index 7356598..b2aaec2 100644
--- a/po/it.po
+++ b/po/it.po
@@ -391,6 +391,9 @@ msgstr ""
msgid "enable ssh support"
msgstr "non gestito"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable putty support"
@@ -416,6 +419,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr ""
+msgid "selected digest algorithm is invalid\n"
+msgstr "l'algoritmo di digest selezionato non è valido\n"
+
#, fuzzy, c-format
#| msgid "NOTE: no default option file `%s'\n"
msgid "Note: no default option file '%s'\n"
@@ -1280,6 +1286,11 @@ msgid "WARNING: %s\n"
msgstr "ATTENZIONE: %s ha la precedenza su %s\n"
#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s non funziona ancora con %s\n"
+
+#, fuzzy, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "la chiave segreta non è disponibile"
@@ -1348,10 +1359,6 @@ msgstr ""
msgid "URL to retrieve public key: "
msgstr "non c'è una chiave pubblica corrispondente: %s\n"
-#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy, c-format
#| msgid "error reading `%s': %s\n"
msgid "error reading '%s': %s\n"
@@ -1364,17 +1371,9 @@ msgstr "errore scrivendo il portachiavi `%s': %s\n"
msgid "Login data (account name): "
msgstr ""
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr ""
-
msgid "Private DO data: "
msgstr ""
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy
msgid "Language preferences: "
msgstr "preferenze aggiornate"
@@ -1681,6 +1680,14 @@ msgstr ""
"del destinatario\n"
#, fuzzy, c-format
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "non è possibile usare l'algoritmo di cifratura \"%s\" in modalità %s\n"
+
+#, fuzzy, c-format
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "ATTENZIONE: \"%s\" è una opzione deprecata\n"
+
+#, fuzzy, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
"preferences\n"
@@ -1698,8 +1705,9 @@ msgstr ""
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s cifrato per: \"%s\"\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "non è possibile usare %s in modalità %s\n"
#, c-format
@@ -1878,6 +1886,10 @@ msgstr "Chiave %08lX non valida resa valida da --allow-non-selfsigned-uid\n"
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 "valid values for option '%s':\n"
+msgstr "opzioni di importazione non valide\n"
+
#, fuzzy
msgid "make a signature"
msgstr "fai una firma separata"
@@ -2227,10 +2239,6 @@ msgid "show expiration dates during signature listings"
msgstr "Manca la firma corrispondente nel portachiavi segreto\n"
#, fuzzy, c-format
-msgid "valid values for option '%s':\n"
-msgstr "opzioni di importazione non valide\n"
-
-#, fuzzy, c-format
msgid "unknown TOFU policy '%s'\n"
msgstr "destinatario predefinito `%s' sconosciuto\n"
@@ -2238,10 +2246,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr ""
#, fuzzy, c-format
-msgid "invalid value for option '%s'\n"
-msgstr "opzioni di importazione non valide\n"
-
-#, fuzzy, c-format
#| msgid "NOTE: old default options file `%s' ignored\n"
msgid "Note: old default options file '%s' ignored\n"
msgstr ""
@@ -2387,9 +2391,6 @@ msgstr "scrittura della chiave segreta in `%s'\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "l'algoritmo di cifratura selezionato non è valido\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "l'algoritmo di digest selezionato non è valido\n"
-
#, fuzzy
msgid "selected compression algorithm is invalid\n"
msgstr "l'algoritmo di cifratura selezionato non è valido\n"
@@ -2438,15 +2439,11 @@ 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"
-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 "digest algorithm '%s' may not be used 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 "compression algorithm '%s' may not be used in %s mode\n"
msgstr ""
"non è possibile usare l'algoritmo di compressione \"%s\" in modalità %s\n"
@@ -2467,14 +2464,14 @@ msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "non è possibile usare %s in modalità %s\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "non è possibile usare %s in modalità %s\n"
#, c-format
@@ -2605,6 +2602,10 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr ""
+#, fuzzy
+msgid "repair keys on import"
+msgstr "mostra le impronte digitali"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "salto un blocco di tipo %d\n"
@@ -2995,59 +2996,6 @@ msgstr "[revoca]"
msgid "[self-signature]"
msgstr "[autofirma]"
-#, fuzzy, c-format
-msgid "error allocating memory: %s\n"
-msgstr "errore creando il portachiavi `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "chiave %08lX: algoritmo a chiave pubblica non gestito\n"
-
-#, fuzzy, c-format
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "Firma %s, algoritmo di digest %s\n"
-
-#, fuzzy
-msgid " (reordered signatures follow)"
-msgstr "Firma valida da \""
-
-#, fuzzy, c-format
-msgid "key %s:\n"
-msgstr "saltata `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "L'user ID \"%s\" è stato revocato."
-msgstr[1] "L'user ID \"%s\" è stato revocato."
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "una firma non controllata per mancanza della chiave\n"
-msgstr[1] "una firma non controllata per mancanza della chiave\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d firme non corrette\n"
-msgstr[1] "%d firme non corrette\n"
-
-#, fuzzy, c-format
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "Firma valida da \""
-msgstr[1] "Firma valida da \""
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
#, fuzzy
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
@@ -3575,6 +3523,14 @@ msgstr "Niente da firmare con la chiave %08lX\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "%s non è un set di caratteri valido\n"
+#, fuzzy, c-format
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "errore: impronta digitale non valida\n"
+
+#, fuzzy, c-format
+msgid "subkey \"%s\" not found\n"
+msgstr "chiave `%s' non trovata: %s\n"
+
msgid "Digest: "
msgstr "Digest: "
@@ -3922,6 +3878,10 @@ msgstr ""
"Mostro %s ID fotografici di dimensioni %ld per la chaive 0x%08lX (uid %d)\n"
#, fuzzy, c-format
+msgid "invalid value for option '%s'\n"
+msgstr "opzioni di importazione non valide\n"
+
+#, fuzzy, c-format
msgid "preference '%s' duplicated\n"
msgstr "la preferenza %c%lu è doppia\n"
@@ -4412,6 +4372,20 @@ msgstr[0] "%d firme non corrette\n"
msgstr[1] "%d firme non corrette\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d firme non corrette\n"
+msgstr[1] "%d firme non corrette\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "una firma non controllata per mancanza della chiave\n"
+msgstr[1] "una firma non controllata per mancanza della chiave\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4691,6 +4665,11 @@ msgstr "[incerta]"
msgid " aka \"%s\""
msgstr " alias \""
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr "ATTENZIONE: questa chiave non è certificata con una firma fidata!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "Firma scaduta il %s\n"
@@ -5254,6 +5233,10 @@ msgid "can't open signed data fd=%d: %s\n"
msgstr "impossibile aprire i dati firmati `%s'\n"
#, fuzzy, c-format
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "chiave %08lX: nessun user ID\n"
+
+#, fuzzy, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "destinatario anonimo; provo la chiave segreta %08lX ...\n"
@@ -5431,6 +5414,11 @@ msgid "WARNING: signature digest conflict in message\n"
msgstr "ATTENZIONE: conflitto del digest delle firme nel messaggio\n"
#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "non è possibile usare %s in modalità %s\n"
+
+#, fuzzy, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr ""
"ATTENZIONE: la sottochiave per firme %08lX non ha una certificature "
@@ -8226,6 +8214,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr ""
#, fuzzy, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "errore leggendo `%s': %s\n"
+
+#, fuzzy, c-format
+msgid "error allocating memory: %s\n"
+msgstr "errore creando il portachiavi `%s': %s\n"
+
+#, fuzzy, c-format
msgid "error printing log line: %s\n"
msgstr "errore scrivendo il portachiavi `%s': %s\n"
@@ -8333,10 +8329,6 @@ msgid "error reading HTTP response for '%s': %s\n"
msgstr "errore leggendo `%s': %s\n"
#, fuzzy, c-format
-msgid "error accessing '%s': http status %u\n"
-msgstr "errore leggendo `%s': %s\n"
-
-#, fuzzy, c-format
msgid "error parsing OCSP response for '%s': %s\n"
msgstr "errore leggendo `%s': %s\n"
@@ -8954,6 +8946,36 @@ msgid ""
msgstr ""
#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "chiave %08lX: algoritmo a chiave pubblica non gestito\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "Firma %s, algoritmo di digest %s\n"
+
+#, fuzzy
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "Firma valida da \""
+
+#, fuzzy
+#~ msgid "key %s:\n"
+#~ msgstr "saltata `%s': %s\n"
+
+#, fuzzy
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "L'user ID \"%s\" è stato revocato."
+#~ msgstr[1] "L'user ID \"%s\" è stato revocato."
+
+#, fuzzy
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "Firma valida da \""
+#~ msgstr[1] "Firma valida da \""
+
+#, fuzzy
#~| msgid "new configuration file `%s' created\n"
#~ msgid "new configuration file '%s' created\n"
#~ msgstr "creato un nuovo file di configurazione `%s'\n"
diff --git a/po/ja.po b/po/ja.po
index 97ac30b..32bc34d 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -369,6 +369,9 @@ msgstr "Emacsを通じてパスフレーズを催促することを認める"
msgid "enable ssh support"
msgstr "sshサポートを有功にする"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
msgid "enable putty support"
msgstr "puttyサポートを有功にする"
@@ -392,6 +395,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr "無効なdebug-level '%s'が与えられました\n"
+msgid "selected digest algorithm is invalid\n"
+msgstr "選択されたダイジェスト・アルゴリズムは、無効です\n"
+
#, c-format
msgid "Note: no default option file '%s'\n"
msgstr "*注意*: デフォルトのオプション・ファイル '%s' がありません\n"
@@ -1194,6 +1200,11 @@ msgstr "サーバ'%s'はこちらより古いです(%s < %s)"
msgid "WARNING: %s\n"
msgstr "*警告*: %s\n"
+#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%sは%sではまだ機能しません\n"
+
#, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "OpenPGPカードが利用できません: %s\n"
@@ -1255,10 +1266,6 @@ msgid "URL to retrieve public key: "
msgstr "公開鍵を取得するURL: "
#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr "エラー: URLが長すぎます (上限%d文字)。\n"
-
-#, c-format
msgid "error reading '%s': %s\n"
msgstr "'%s'の読み込みエラー: %s\n"
@@ -1269,17 +1276,9 @@ msgstr "'%s'の書き込みエラー: %s\n"
msgid "Login data (account name): "
msgstr "ログイン・データ (アカウント名): "
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr "エラー: ログイン・データが長すぎます (上限%d文字)。\n"
-
msgid "Private DO data: "
msgstr "プライベート DO データ: "
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr "エラー: プライベート DOが長すぎます (上限%d文字)。\n"
-
msgid "Language preferences: "
msgstr "言語の優先指定: "
@@ -1555,6 +1554,17 @@ msgid ""
msgstr ""
"*警告*: 共通鍵暗号方式 %s (%d) の強制が、受取人の優先指定をそむきます\n"
+#, fuzzy, c-format
+#| msgid "you may not use cipher algorithm '%s' while in %s mode\n"
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "暗号アルゴリズム'%s'を%sモードで使うことはできません\n"
+
+#, fuzzy, c-format
+#| msgid "WARNING: \"%s%s\" is an obsolete option - it has no effect\n"
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr ""
+"*警告*: \"%s%s\"は、使われなくなったオプションです - なんの効果もありません\n"
+
#, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
@@ -1570,8 +1580,9 @@ msgstr "共通鍵暗号方式 %s (%d) の強制が、受取人の優先指定を
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s暗号化 受信者:\"%s\"\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "%sを%sモードで使うことはできません\n"
#, c-format
@@ -1729,6 +1740,10 @@ msgstr "--allow-non-selfsigned-uidで有効にされた無効な鍵%sです\n"
msgid "using subkey %s instead of primary key %s\n"
msgstr "副鍵%s(主鍵%sではなく)を用います\n"
+#, c-format
+msgid "valid values for option '%s':\n"
+msgstr "オプション'%s'に有効な値:\n"
+
msgid "make a signature"
msgstr "署名を作成"
@@ -2037,10 +2052,6 @@ msgid "show expiration dates during signature listings"
msgstr "署名の一覧時に有効期限の日付を表示する"
#, c-format
-msgid "valid values for option '%s':\n"
-msgstr "オプション'%s'に有効な値:\n"
-
-#, c-format
msgid "unknown TOFU policy '%s'\n"
msgstr "不明のTOFUポリシー'%s'\n"
@@ -2048,10 +2059,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr "(選択肢の一覧には\"help\"を使ってください)\n"
#, c-format
-msgid "invalid value for option '%s'\n"
-msgstr "オプション'%s'に無効な値です\n"
-
-#, c-format
msgid "Note: old default options file '%s' ignored\n"
msgstr "*注意*: 以前デフォルトだったオプション・ファイル'%s'は、無視されます\n"
@@ -2186,9 +2193,6 @@ msgstr "%s のため、セキュアでないメモリで実行しません\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "選択された暗号アルゴリズムは、無効です\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "選択されたダイジェスト・アルゴリズムは、無効です\n"
-
msgid "selected compression algorithm is invalid\n"
msgstr "選択された圧縮アルゴリズムは、無効です\n"
@@ -2232,16 +2236,14 @@ msgstr "無効な個人用圧縮の優先指定\n"
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"
-
-#, c-format
-msgid "you may not use digest algorithm '%s' while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use digest algorithm '%s' while in %s mode\n"
+msgid "digest algorithm '%s' may not be used in %s mode\n"
msgstr "ダイジェスト・アルゴリズム'%s'を%sモードで使うことはできません\n"
-#, c-format
-msgid "you may not use compression algorithm '%s' while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use compression algorithm '%s' while in %s mode\n"
+msgid "compression algorithm '%s' may not be used in %s mode\n"
msgstr "圧縮アルゴリズム'%s'を%sモードで使うことはできません\n"
#, c-format
@@ -2258,15 +2260,17 @@ msgstr "'%s'の共通鍵暗号に失敗しました: %s\n"
msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr "--symmetric --encryptを--s2k-mode 0で使うことはできません\n"
-#, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "--symmetric --encryptを%sモードで使うことはできません\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr "--symmetric --sign --encryptを--s2k-mode 0で使うことはできません\n"
-#, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "--symmetric --sign --encryptを%sモードで使うことはできません\n"
#, c-format
@@ -2388,6 +2392,11 @@ msgstr "インポート・フィルタを実行し鍵をすぐにエクスポー
msgid "assume the GnuPG key backup format"
msgstr "GnuPGの鍵のバックアップフォーマットを仮定します"
+#, fuzzy
+#| msgid "show key during import"
+msgid "repair keys on import"
+msgstr "インポートの際、鍵を表示"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "型%dのブロックをスキップします\n"
@@ -2767,55 +2776,6 @@ msgstr "[失効]"
msgid "[self-signature]"
msgstr "[自己署名]"
-#, c-format
-msgid "error allocating memory: %s\n"
-msgstr "メモリの確保のエラー: %s\n"
-
-#, c-format
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "サポートしていない公開鍵アルゴリズム(%d)の署名は確認できません: %s.\n"
-
-#, c-format
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr ""
-"サポートしていないメッセージ・ダイジェスト(%d)の署名は確認できません: %s.\n"
-
-msgid " (reordered signatures follow)"
-msgstr "(順番を変えた署名が続きます)"
-
-#, c-format
-msgid "key %s:\n"
-msgstr "鍵 %s:\n"
-
-#, c-format
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "%d個の重複した署名が除去されました\n"
-
-#, c-format
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "鍵がないため%d個の署名は検査しません\n"
-
-#, c-format
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d個の不正な署名\n"
-
-#, c-format
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "%d個の正しい署名\n"
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-"警告: エラーがあり、自己署名だけ確認しました。'%s'を実行してすべての署名を確"
-"認ください。\n"
-
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
"keys\n"
@@ -3275,6 +3235,16 @@ msgstr "署名するものがありません。\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "'%s'は、有効な有効期限ではありません\n"
+#, fuzzy, c-format
+#| msgid "\"%s\" is not a fingerprint\n"
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "\"%s\"はフィンガープリントではありません\n"
+
+#, fuzzy, c-format
+#| msgid "key \"%s\" not found\n"
+msgid "subkey \"%s\" not found\n"
+msgstr "鍵\"%s\"が見つかりません\n"
+
msgid "Digest: "
msgstr "ダイジェスト: "
@@ -3585,6 +3555,10 @@ 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 "invalid value for option '%s'\n"
+msgstr "オプション'%s'に無効な値です\n"
+
+#, c-format
msgid "preference '%s' duplicated\n"
msgstr "優先指定'%s'の重複\n"
@@ -4045,6 +4019,16 @@ msgid_plural "%d good signatures\n"
msgstr[0] "正しい署名%d個\n"
#, c-format
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d個の不正な署名\n"
+
+#, c-format
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "鍵がないため%d個の署名は検査しません\n"
+
+#, c-format
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
msgstr[0] "エラーのため%d個の署名を検査しません\n"
@@ -4304,6 +4288,11 @@ msgstr "[不確定]"
msgid " aka \"%s\""
msgstr " 別名\"%s\""
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr "*警告*: この鍵は信用できる署名で証明されていません!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "期限切れの署名 %s\n"
@@ -4832,6 +4821,11 @@ msgstr "署名されたデータ'%s'が開けません\n"
msgid "can't open signed data fd=%d: %s\n"
msgstr "署名されたデータ fd=%d が開けません: %s\n"
+#, fuzzy, c-format
+#| msgid "certificate is not usable for encryption\n"
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "証明書は暗号化のために使えません\n"
+
#, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "匿名の受取人用です。秘密鍵%sを試します ...\n"
@@ -5008,6 +5002,11 @@ msgstr ""
msgid "WARNING: signature digest conflict in message\n"
msgstr "*警告*: 署名のダイジェストが、メッセージと衝突します\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "%sを%sモードで使うことはできません\n"
+
#, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr "*警告*: 署名副鍵%sは、相互証明されてません\n"
@@ -7627,6 +7626,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr "'%s' は無効なLDAP URLです\n"
#, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "'%s'へアクセスのエラー: httpステイタス %u\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"
@@ -7730,10 +7737,6 @@ 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"
@@ -8322,6 +8325,47 @@ msgstr ""
"形式: gpg-check-pattern [オプション] パターンファイル\n"
"パターンファイルに対して標準入力のパスフレーズを確認する\n"
+#~ msgid "Error: URL too long (limit is %d characters).\n"
+#~ msgstr "エラー: URLが長すぎます (上限%d文字)。\n"
+
+#~ msgid "Error: Login data too long (limit is %d characters).\n"
+#~ msgstr "エラー: ログイン・データが長すぎます (上限%d文字)。\n"
+
+#~ msgid "Error: Private DO too long (limit is %d characters).\n"
+#~ msgstr "エラー: プライベート DOが長すぎます (上限%d文字)。\n"
+
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr ""
+#~ "サポートしていない公開鍵アルゴリズム(%d)の署名は確認できません: %s.\n"
+
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr ""
+#~ "サポートしていないメッセージ・ダイジェスト(%d)の署名は確認できません: "
+#~ "%s.\n"
+
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "(順番を変えた署名が続きます)"
+
+#~ msgid "key %s:\n"
+#~ msgstr "鍵 %s:\n"
+
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "%d個の重複した署名が除去されました\n"
+
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "%d個の正しい署名\n"
+
+#~ msgid ""
+#~ "Warning: errors found and only checked self-signatures, run '%s' to check "
+#~ "all signatures.\n"
+#~ msgstr ""
+#~ "警告: エラーがあり、自己署名だけ確認しました。'%s'を実行してすべての署名を"
+#~ "確認ください。\n"
+
#~ msgid ", "
#~ msgstr ", "
diff --git a/po/nb.po b/po/nb.po
index 9de4f45..09e8fc2 100644
--- a/po/nb.po
+++ b/po/nb.po
@@ -376,6 +376,9 @@ msgstr "la brukeren skrive inn passordfrase via Emacs"
msgid "enable ssh support"
msgstr "slå på ssh-støtte"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
msgid "enable putty support"
msgstr "slå på støtte for putty"
@@ -399,6 +402,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr "«%s» er et ugyldig feilsøkingsnivå\n"
+msgid "selected digest algorithm is invalid\n"
+msgstr "valg kontrollsum-algoritme er ugyldig\n"
+
#, c-format
msgid "Note: no default option file '%s'\n"
msgstr "Merk: standardvalg-fil «%s» finnes ikke\n"
@@ -1204,6 +1210,11 @@ msgstr "tjener «%s» er eldre enn oss (%s < %s)"
msgid "WARNING: %s\n"
msgstr "ADVARSEL: %s\n"
+#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s virker ikke enda med %s\n"
+
#, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "OpenPGP-kort er ikke tilgjengelig: %s\n"
@@ -1265,10 +1276,6 @@ msgid "URL to retrieve public key: "
msgstr "Adresse for henting av offentlig nøkkel: "
#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr "Feil: Adressen er for lang (grensa er %d tegn).\n"
-
-#, c-format
msgid "error reading '%s': %s\n"
msgstr "feil under lesing av «%s»: %s\n"
@@ -1279,17 +1286,9 @@ msgstr "feil under skriving av «%s»: %s\n"
msgid "Login data (account name): "
msgstr "Logindata (kontonavn): "
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr "Feil: Logindata er for langt (grensa går ved %d tegn).\n"
-
msgid "Private DO data: "
msgstr "Privat DO-data: "
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr "Feil: Privat DO for lang (grensa går ved %d tegn).\n"
-
msgid "Language preferences: "
msgstr "Språkoppsett: "
@@ -1567,6 +1566,16 @@ msgstr ""
"ADVARSEL: tvungen bruk av symmetrisk krypt.metode %s (%d) bryter med "
"mottakers oppsett\n"
+#, fuzzy, c-format
+#| msgid "you may not use cipher algorithm '%s' while in %s mode\n"
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "du kan ikke bruke krypteringsalgoritme «%s» i %s-modus\n"
+
+#, fuzzy, c-format
+#| msgid "WARNING: \"%s%s\" is an obsolete option - it has no effect\n"
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "ADVARSEL: valget «%s%s» er utgått, og har ingen effekt\n"
+
#, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
@@ -1583,8 +1592,9 @@ msgstr "tvungen bruk av krypt.metode %s (%d) bryter med mottakers oppsett\n"
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s kryptert for: «%s»\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "du kan ikke bruke «%s» i «%s»-modus\n"
#, c-format
@@ -1744,6 +1754,11 @@ msgstr "Ugyldig nøkkel %s gjort gyldig av --allow-non-selfsigned-uid\n"
msgid "using subkey %s instead of primary key %s\n"
msgstr "bruker undernøkkel %s i stedet for primærnøkkel %s\n"
+#, fuzzy, c-format
+#| msgid "invalid argument for option \"%.50s\"\n"
+msgid "valid values for option '%s':\n"
+msgstr "ugyldig argument for valget «%.50s»\n"
+
msgid "make a signature"
msgstr "lag signatur"
@@ -2061,11 +2076,6 @@ msgstr "vis nøkkelknippe-navn i nøkkelvisning"
msgid "show expiration dates during signature listings"
msgstr "vis utløpsdatoer i nøkkelvisning"
-#, fuzzy, c-format
-#| msgid "invalid argument for option \"%.50s\"\n"
-msgid "valid values for option '%s':\n"
-msgstr "ugyldig argument for valget «%.50s»\n"
-
#, c-format
msgid "unknown TOFU policy '%s'\n"
msgstr "«%s» er et ukjent TOFU-regelverk\n"
@@ -2073,11 +2083,6 @@ msgstr "«%s» er et ukjent TOFU-regelverk\n"
msgid "(use \"help\" to list choices)\n"
msgstr "(bruk «help» for å vise valg)\n"
-#, fuzzy, c-format
-#| msgid "invalid argument for option \"%.50s\"\n"
-msgid "invalid value for option '%s'\n"
-msgstr "ugyldig argument for valget «%.50s»\n"
-
#, c-format
msgid "Note: old default options file '%s' ignored\n"
msgstr "Merk: gammel standardvalgfil «%s» ble ignorert\n"
@@ -2214,9 +2219,6 @@ msgstr "lar være å kjøre med usikret minne på grunn av %s\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "valgt krypteringsalgoritme er ugyldig\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "valg kontrollsum-algoritme er ugyldig\n"
-
msgid "selected compression algorithm is invalid\n"
msgstr "valgt komprimeringsalgoritme er ugyldig\n"
@@ -2260,16 +2262,14 @@ msgstr "ugyldig personlig oppsett av komprimeringsmetode\n"
msgid "%s does not yet work with %s\n"
msgstr "%s virker ikke enda med %s\n"
-#, c-format
-msgid "you may not use cipher algorithm '%s' while in %s mode\n"
-msgstr "du kan ikke bruke krypteringsalgoritme «%s» i %s-modus\n"
-
-#, c-format
-msgid "you may not use digest algorithm '%s' while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use digest algorithm '%s' while in %s mode\n"
+msgid "digest algorithm '%s' may not be used in %s mode\n"
msgstr "du kan ikke bruke summeringsalgoritme «%s» i %s-modus\n"
-#, c-format
-msgid "you may not use compression algorithm '%s' while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use compression algorithm '%s' while in %s mode\n"
+msgid "compression algorithm '%s' may not be used in %s mode\n"
msgstr "du kan ikke bruke komprimeringsalgoritme «%s» i «%s»-modus\n"
#, c-format
@@ -2286,16 +2286,18 @@ msgstr "symmetrisk kryptering av «%s» mislyktes: %s\n"
msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr "du kan ikke bruke «--symmetric --encrypt» og «--s2k-mode 0» samtidig\n"
-#, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "du kan ikke velge «--symmtric» og «--encrypt» i «%s»-modus\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr ""
"du kan ikke bruke «--symmetric --sign --encrypt» og «--s2k-mode 0» samtidig\n"
-#, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "du kan ikke velge «--symmtric», «--sign» og «--encrypt» i «%s»-modus\n"
#, c-format
@@ -2420,6 +2422,11 @@ msgstr "kjør importeringsfiltre og eksporter nøkkel umiddelbart"
msgid "assume the GnuPG key backup format"
msgstr "forvent inndata i binærformat"
+#, fuzzy
+#| msgid "show key during import"
+msgid "repair keys on import"
+msgstr "vis nøkkel under importering"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "hopper over blokk av typen %d\n"
@@ -2807,62 +2814,6 @@ msgstr "[oppheving]"
msgid "[self-signature]"
msgstr "[selvsignatur]"
-#, c-format
-msgid "error allocating memory: %s\n"
-msgstr "feil under minnetildeling: %s\n"
-
-#, c-format
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr ""
-"klarte ikke å kontrollere signatur på grunn av ustøttet algoritme for "
-"offentlig nøkkel (%d): %s.\n"
-
-#, c-format
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr ""
-"klarte ikke å kontrollere signatur på grunn av ustøttet algoritme for "
-"meldingssum (%d): %s.\n"
-
-msgid " (reordered signatures follow)"
-msgstr " (omsorterte signaturer følger)"
-
-#, c-format
-msgid "key %s:\n"
-msgstr "nøkkel %s:\n"
-
-#, c-format
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "%d duplikatsignatur fjernet\n"
-msgstr[1] "%d duplikatsignaturer fjernet\n"
-
-#, c-format
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "%d signatur ble ikke kontrollert på grunn av manglende nøkkel\n"
-msgstr[1] "%d signaturer ble ikke kontrollert på grunn av manglende nøkkel\n"
-
-#, c-format
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d ubrukelig signatur\n"
-msgstr[1] "%d ubrukelige signaturer\n"
-
-#, c-format
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "%d signatur omsortert\n"
-msgstr[1] "%d signaturer omsortert\n"
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-"Advarsel: fant feil og kontrollerte bare selvsignaturer. Kjør «%s» for å "
-"kontrollere alle signaturer.\n"
-
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
"keys\n"
@@ -3339,6 +3290,16 @@ msgstr "Ingenting å signere.\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "«%s» er en ugyldig signatur-utløpstid\n"
+#, fuzzy, c-format
+#| msgid "\"%s\" is not a fingerprint\n"
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "«%s» er ikke et fingeravtrykk\n"
+
+#, fuzzy, c-format
+#| msgid "key \"%s\" not found\n"
+msgid "subkey \"%s\" not found\n"
+msgstr "fant ikke nøkkelen «%s»\n"
+
msgid "Digest: "
msgstr "Kontrollsum: "
@@ -3655,6 +3616,11 @@ msgstr "Undernøkkel %s er allerede opphevet.\n"
msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
msgstr "Viser %s foto-ID av størrelsen %ld for nøkkel %s (uid %d)\n"
+#, fuzzy, c-format
+#| msgid "invalid argument for option \"%.50s\"\n"
+msgid "invalid value for option '%s'\n"
+msgstr "ugyldig argument for valget «%.50s»\n"
+
#, c-format
msgid "preference '%s' duplicated\n"
msgstr "innstilling «%s» er duplisert\n"
@@ -4129,6 +4095,18 @@ msgstr[0] "%d gyldig signatur\n"
msgstr[1] "%d gyldige signaturer\n"
#, c-format
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d ubrukelig signatur\n"
+msgstr[1] "%d ubrukelige signaturer\n"
+
+#, c-format
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "%d signatur ble ikke kontrollert på grunn av manglende nøkkel\n"
+msgstr[1] "%d signaturer ble ikke kontrollert på grunn av manglende nøkkel\n"
+
+#, c-format
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
msgstr[0] "%d signatur ble ikke kontrollert på grunn av feil\n"
@@ -4397,6 +4375,12 @@ msgstr "[usikker]"
msgid " aka \"%s\""
msgstr " aka «%s»"
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr ""
+"ADVARSEL: denne nøkkelen er ikke sertifisert med en tillitsverdig signatur.\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "Signatur utgått %s\n"
@@ -4935,6 +4919,11 @@ msgstr "klarte ikke å åpne signert data «%s»\n"
msgid "can't open signed data fd=%d: %s\n"
msgstr "klarte ikke å åpne signert data fd=%d: «%s»\n"
+#, fuzzy, c-format
+#| msgid "certificate is not usable for encryption\n"
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "sertifikatet egner seg ikke til kryptering\n"
+
#, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "anonym mottaker. prøver hemmelig nøkkel %s …\n"
@@ -5116,6 +5105,11 @@ msgstr ""
msgid "WARNING: signature digest conflict in message\n"
msgstr "ADVARSEL: konflikt med signatur-kontrollsum i melding\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "du kan ikke bruke «%s» i «%s»-modus\n"
+
#, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr "ADVARSEL: undernøkkel %s for signering er ikke kryssertifisert\n"
@@ -7889,6 +7883,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr "«%s» er en ugyldig LDAP-adresse\n"
#, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "fikk ikke tilgang til «%s»: http-status %u\n"
+
+#, c-format
+msgid "error allocating memory: %s\n"
+msgstr "feil under minnetildeling: %s\n"
+
+#, c-format
msgid "error printing log line: %s\n"
msgstr "feil under utskrift av logglinje: %s\n"
@@ -7992,10 +7994,6 @@ msgid "error reading HTTP response for '%s': %s\n"
msgstr "feil under lesing av HTTP-svar for «%s»: %s\n"
#, c-format
-msgid "error accessing '%s': http status %u\n"
-msgstr "fikk ikke tilgang til «%s»: http-status %u\n"
-
-#, c-format
msgid "error parsing OCSP response for '%s': %s\n"
msgstr "feil under tolking av OCSP-svar for «%s»: %s\n"
@@ -8602,6 +8600,50 @@ msgstr ""
"Syntaks: gpg-check-pattern [valg] mønsterfil\n"
"Kontroller passordfrase oppgitt på standard innkanal mot valgt mønsterfil\n"
+#~ msgid "Error: URL too long (limit is %d characters).\n"
+#~ msgstr "Feil: Adressen er for lang (grensa er %d tegn).\n"
+
+#~ msgid "Error: Login data too long (limit is %d characters).\n"
+#~ msgstr "Feil: Logindata er for langt (grensa går ved %d tegn).\n"
+
+#~ msgid "Error: Private DO too long (limit is %d characters).\n"
+#~ msgstr "Feil: Privat DO for lang (grensa går ved %d tegn).\n"
+
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr ""
+#~ "klarte ikke å kontrollere signatur på grunn av ustøttet algoritme for "
+#~ "offentlig nøkkel (%d): %s.\n"
+
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr ""
+#~ "klarte ikke å kontrollere signatur på grunn av ustøttet algoritme for "
+#~ "meldingssum (%d): %s.\n"
+
+#~ msgid " (reordered signatures follow)"
+#~ msgstr " (omsorterte signaturer følger)"
+
+#~ msgid "key %s:\n"
+#~ msgstr "nøkkel %s:\n"
+
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "%d duplikatsignatur fjernet\n"
+#~ msgstr[1] "%d duplikatsignaturer fjernet\n"
+
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "%d signatur omsortert\n"
+#~ msgstr[1] "%d signaturer omsortert\n"
+
+#~ msgid ""
+#~ "Warning: errors found and only checked self-signatures, run '%s' to check "
+#~ "all signatures.\n"
+#~ msgstr ""
+#~ "Advarsel: fant feil og kontrollerte bare selvsignaturer. Kjør «%s» for å "
+#~ "kontrollere alle signaturer.\n"
+
#~ msgid "new configuration file '%s' created\n"
#~ msgstr "ny oppsettsfil «%s» opprettet\n"
diff --git a/po/pl.po b/po/pl.po
index beb85e5..4df8e68 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -416,6 +416,9 @@ msgstr ""
msgid "enable ssh support"
msgstr ""
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
msgid "enable putty support"
msgstr ""
@@ -446,6 +449,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr "podano błędny poziom diagnostyki ,,%s''\n"
+msgid "selected digest algorithm is invalid\n"
+msgstr "wybrany algorytm skrótów wiadomości jest niepoprawny\n"
+
#, fuzzy, c-format
#| msgid "NOTE: no default option file `%s'\n"
msgid "Note: no default option file '%s'\n"
@@ -1311,6 +1317,11 @@ msgstr ""
msgid "WARNING: %s\n"
msgstr "OSTRZEŻENIE: %s powoduje obejście %s\n"
+#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s jeszcze nie działa z %s!\n"
+
#, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "Karta OpenPGP niedostępna: %s\n"
@@ -1371,10 +1382,6 @@ 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"
-
#, fuzzy, c-format
#| msgid "error reading `%s': %s\n"
msgid "error reading '%s': %s\n"
@@ -1388,17 +1395,9 @@ msgstr "błąd zapisu ,,%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"
-
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"
-
msgid "Language preferences: "
msgstr "Preferowane języki: "
@@ -1702,6 +1701,16 @@ msgstr ""
"OSTRZEŻENIE: wymuszone użycie szyfru %s (%d) kłóci się z ustawieniami "
"adresata\n"
+#, fuzzy, c-format
+#| msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "szyfr ,,%s'' nie jest dostępny w trybie %s\n"
+
+#, fuzzy, c-format
+#| msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "OSTRZEŻENIE: ,,%s'' jest przestarzałą opcją - nie ma efektu\n"
+
#, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
@@ -1718,8 +1727,9 @@ msgstr "wymuszone użycie szyfru %s (%d) kłóci się z ustawieniami adresata\n"
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s zaszyfrowany dla: ,,%s''\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "%s nie jest dostępne w trybie %s\n"
#, c-format
@@ -1894,6 +1904,11 @@ msgstr ""
msgid "using subkey %s instead of primary key %s\n"
msgstr "używany jest podklucz %s zamiast klucza głównego %s\n"
+#, fuzzy, c-format
+#| msgid "missing argument for option \"%.50s\"\n"
+msgid "valid values for option '%s':\n"
+msgstr "brak argumentu dla opcji ,,%.50s''\n"
+
msgid "make a signature"
msgstr "złożenie podpisu"
@@ -2270,11 +2285,6 @@ msgid "show expiration dates during signature listings"
msgstr "pokazywanie dat wygaśnięcia przy wypisywaniu podpisów"
#, fuzzy, c-format
-#| msgid "missing argument for option \"%.50s\"\n"
-msgid "valid values for option '%s':\n"
-msgstr "brak argumentu dla opcji ,,%.50s''\n"
-
-#, fuzzy, c-format
#| msgid "unknown option `%s'\n"
msgid "unknown TOFU policy '%s'\n"
msgstr "nieznana opcja ,,%s''\n"
@@ -2283,11 +2293,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr ""
#, fuzzy, c-format
-#| msgid "missing argument for option \"%.50s\"\n"
-msgid "invalid value for option '%s'\n"
-msgstr "brak argumentu dla opcji ,,%.50s''\n"
-
-#, fuzzy, c-format
#| msgid "NOTE: old default options file `%s' ignored\n"
msgid "Note: old default options file '%s' ignored\n"
msgstr "UWAGA: stary domyślny plik opcji ,,%s'' został zignorowany\n"
@@ -2432,9 +2437,6 @@ msgstr "nie zadziała z niebezpieczną pamięcią z powodu %s\n"
msgid "selected cipher algorithm is invalid\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"
-
msgid "selected compression algorithm is invalid\n"
msgstr "wybrany algorytm kompresji jest niepoprawny\n"
@@ -2483,18 +2485,13 @@ msgid "%s does not yet work with %s\n"
msgstr "%s jeszcze nie działa z %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 "szyfr ,,%s'' nie jest dostępny w trybie %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"
+msgid "digest algorithm '%s' may not be used in %s mode\n"
msgstr "skrót ,,%s'' nie jest dostępny w trybie %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"
+msgid "compression algorithm '%s' may not be used in %s mode\n"
msgstr "kompresja ,,%s'' nie jest dostępna w trybie %s\n"
#, c-format
@@ -2512,15 +2509,17 @@ msgstr "szyfrowanie symetryczne ,,%s'' nie powiodło się: %s\n"
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"
-#, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "nie można użyć --symmetric --encrypt w trybie %s\n"
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"
-#, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "nie można użyć --symmetric --sign --encrypt w trybie %s\n"
#, c-format
@@ -2651,6 +2650,11 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr "przyjęcie wejścia w formacie binarnym"
+#, fuzzy
+#| msgid "show key fingerprint"
+msgid "repair keys on import"
+msgstr "okazanie odcisku klucza"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "blok typu %d zostaje pominięty\n"
@@ -3051,70 +3055,6 @@ msgstr "[unieważnienie]"
msgid "[self-signature]"
msgstr "[podpis klucza nim samym]"
-#, fuzzy, c-format
-#| msgid "error allocating enough memory: %s\n"
-msgid "error allocating memory: %s\n"
-msgstr "błąd przydzielania wystarczającej ilości pamięci: %s\n"
-
-#, fuzzy, c-format
-#| msgid "key %s: unsupported public key algorithm\n"
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "klucz %s: nieobsługiwany algorytm asymetryczny\n"
-
-#, fuzzy, c-format
-#| msgid "card does not support digest algorithm %s\n"
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "karta nie obsługuje algorytmu skrótu %s\n"
-
-#, fuzzy
-#| msgid "Good signature from"
-msgid " (reordered signatures follow)"
-msgstr "Poprawny podpis złożony przez"
-
-#, fuzzy, c-format
-#| msgid "skipped \"%s\": %s\n"
-msgid "key %s:\n"
-msgstr "pominięty ,,%s'': %s\n"
-
-#, fuzzy, c-format
-#| msgid "User ID \"%s\": %d signature removed\n"
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "Identyfikator użytkownika ,,%s'': %d podpis wyczyszczony\n"
-msgstr[1] "Identyfikator użytkownika ,,%s'': %d podpis wyczyszczony\n"
-msgstr[2] "Identyfikator użytkownika ,,%s'': %d podpis wyczyszczony\n"
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "1 podpis nie został sprawdzony z powodu braku klucza\n"
-msgstr[1] "1 podpis nie został sprawdzony z powodu braku klucza\n"
-msgstr[2] "1 podpis nie został sprawdzony z powodu braku klucza\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d niepoprawnych podpisów\n"
-msgstr[1] "%d niepoprawnych podpisów\n"
-msgstr[2] "%d niepoprawnych podpisów\n"
-
-#, fuzzy, c-format
-#| msgid "Good signature from"
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "Poprawny podpis złożony przez"
-msgstr[1] "Poprawny podpis złożony przez"
-msgstr[2] "Poprawny podpis złożony przez"
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
"keys\n"
@@ -3627,6 +3567,16 @@ msgstr "Nie ma nic do podpisania kluczem %s\n"
msgid "'%s' is not a valid expiration time\n"
msgstr ",,%s'' nie jest poprawnym czasem wygaśnięcia podpisu\n"
+#, fuzzy, c-format
+#| msgid "invalid fingerprint"
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "niewłaściwy odcisk"
+
+#, fuzzy, c-format
+#| msgid "key \"%s\" not found: %s\n"
+msgid "subkey \"%s\" not found\n"
+msgstr "klucz ,,%s'' nie został odnaleziony: %s\n"
+
msgid "Digest: "
msgstr "Skrót: "
@@ -3957,6 +3907,11 @@ msgstr ""
"%d).\n"
#, fuzzy, c-format
+#| msgid "missing argument for option \"%.50s\"\n"
+msgid "invalid value for option '%s'\n"
+msgstr "brak argumentu dla opcji ,,%.50s''\n"
+
+#, fuzzy, c-format
#| msgid "preference `%s' duplicated\n"
msgid "preference '%s' duplicated\n"
msgstr "ustawienie ,,%s'' powtarza się\n"
@@ -4455,6 +4410,22 @@ msgstr[1] "%d niepoprawnych podpisów\n"
msgstr[2] "%d niepoprawnych podpisów\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d niepoprawnych podpisów\n"
+msgstr[1] "%d niepoprawnych podpisów\n"
+msgstr[2] "%d niepoprawnych podpisów\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "1 podpis nie został sprawdzony z powodu braku klucza\n"
+msgstr[1] "1 podpis nie został sprawdzony z powodu braku klucza\n"
+msgstr[2] "1 podpis nie został sprawdzony z powodu braku klucza\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4739,6 +4710,11 @@ msgstr "[niepewne]"
msgid " aka \"%s\""
msgstr " alias ,,%s''"
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr "OSTRZEŻENIE: Ten klucz nie jest poświadczony zaufanym podpisem!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "Ważność podpisu wygasła %s.\n"
@@ -5313,6 +5289,11 @@ msgstr "nie można otworzyć podpisanego pliku ,,%s''\n"
msgid "can't open signed data fd=%d: %s\n"
msgstr "nie można otworzyć podpisanych danych z fd=%d: %s\n"
+#, fuzzy, c-format
+#| msgid "certificate is not usable for encryption\n"
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "certyfikat nie nadaje się do szyfrowania\n"
+
#, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "adresat anonimowy; sprawdzanie klucza tajnego %s...\n"
@@ -5495,6 +5476,11 @@ 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"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "%s nie jest dostępne w trybie %s\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"
@@ -8479,6 +8465,16 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr ""
#, fuzzy, c-format
+#| msgid "error running `%s': exit status %d\n"
+msgid "error accessing '%s': http status %u\n"
+msgstr "błąd uruchamiania ,,%s'': kod wyjścia %d\n"
+
+#, fuzzy, c-format
+#| msgid "error allocating enough memory: %s\n"
+msgid "error allocating memory: %s\n"
+msgstr "błąd przydzielania wystarczającej ilości pamięci: %s\n"
+
+#, fuzzy, c-format
#| msgid "error writing to %s: %s\n"
msgid "error printing log line: %s\n"
msgstr "błąd zapisu do %s: %s\n"
@@ -8601,11 +8597,6 @@ msgid "error reading HTTP response for '%s': %s\n"
msgstr "błąd odczytu z %s: %s\n"
#, fuzzy, c-format
-#| msgid "error running `%s': exit status %d\n"
-msgid "error accessing '%s': http status %u\n"
-msgstr "błąd uruchamiania ,,%s'': kod wyjścia %d\n"
-
-#, fuzzy, c-format
#| msgid "error binding socket to `%s': %s\n"
msgid "error parsing OCSP response for '%s': %s\n"
msgstr "błąd podczas przypisywania gniazda do ,,%s'': %s\n"
@@ -9280,6 +9271,53 @@ 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 "Error: URL too long (limit is %d characters).\n"
+#~ msgstr "Błąd: URL zbyt długi (limit to %d znaków).\n"
+
+#~ 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"
+
+#~ 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"
+
+#, fuzzy
+#~| msgid "key %s: unsupported public key algorithm\n"
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "klucz %s: nieobsługiwany algorytm asymetryczny\n"
+
+#, fuzzy
+#~| msgid "card does not support digest algorithm %s\n"
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "karta nie obsługuje algorytmu skrótu %s\n"
+
+#, fuzzy
+#~| msgid "Good signature from"
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "Poprawny podpis złożony przez"
+
+#, fuzzy
+#~| msgid "skipped \"%s\": %s\n"
+#~ msgid "key %s:\n"
+#~ msgstr "pominięty ,,%s'': %s\n"
+
+#, fuzzy
+#~| msgid "User ID \"%s\": %d signature removed\n"
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "Identyfikator użytkownika ,,%s'': %d podpis wyczyszczony\n"
+#~ msgstr[1] "Identyfikator użytkownika ,,%s'': %d podpis wyczyszczony\n"
+#~ msgstr[2] "Identyfikator użytkownika ,,%s'': %d podpis wyczyszczony\n"
+
+#, fuzzy
+#~| msgid "Good signature from"
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "Poprawny podpis złożony przez"
+#~ msgstr[1] "Poprawny podpis złożony przez"
+#~ msgstr[2] "Poprawny podpis złożony przez"
+
#, fuzzy
#~| msgid "new configuration file `%s' created\n"
#~ msgid "new configuration file '%s' created\n"
diff --git a/po/pt.po b/po/pt.po
index d446cdc..b905742 100644
--- a/po/pt.po
+++ b/po/pt.po
@@ -396,6 +396,9 @@ msgstr ""
msgid "enable ssh support"
msgstr "não suportado"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable putty support"
@@ -421,6 +424,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr ""
+msgid "selected digest algorithm is invalid\n"
+msgstr "o algoritmo de \"digest\" selecionado é inválido\n"
+
#, fuzzy, c-format
#| msgid "NOTE: no default option file `%s'\n"
msgid "Note: no default option file '%s'\n"
@@ -1283,6 +1289,10 @@ msgid "WARNING: %s\n"
msgstr "AVISO: %s sobrepõe %s\n"
#, fuzzy, c-format
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s não faz sentido com %s!\n"
+
+#, fuzzy, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "chave secreta não disponível"
@@ -1350,10 +1360,6 @@ msgstr ""
msgid "URL to retrieve public key: "
msgstr "a escrever chave pública para `%s'\n"
-#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy, c-format
#| msgid "error reading `%s': %s\n"
msgid "error reading '%s': %s\n"
@@ -1366,17 +1372,9 @@ msgstr "erro na escrita do porta-chaves `%s': %s\n"
msgid "Login data (account name): "
msgstr ""
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr ""
-
msgid "Private DO data: "
msgstr ""
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy
msgid "Language preferences: "
msgstr "preferências actualizadas"
@@ -1681,6 +1679,14 @@ msgstr ""
"ao forçar a cifra simétrica %s (%d) viola as preferências do destinatário\n"
#, fuzzy, c-format
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "não pode utilizar %s enquanto estiver no modo %s\n"
+
+#, fuzzy, c-format
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "AVISO: \"%s\" é uma opção depreciada\n"
+
+#, fuzzy, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
"preferences\n"
@@ -1697,8 +1703,9 @@ msgstr ""
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s cifrado para: \"%s\"\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "não pode utilizar %s enquanto estiver no modo %s\n"
#, c-format
@@ -1870,6 +1877,10 @@ msgstr "Chave inválida %08lX tornada válida por --allow-non-selfsigned-uid\n"
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 "valid values for option '%s':\n"
+msgstr "opções de importação inválidas\n"
+
#, fuzzy
msgid "make a signature"
msgstr "fazer uma assinatura separada"
@@ -2223,10 +2234,6 @@ msgid "show expiration dates during signature listings"
msgstr "Nenhuma assinatura correspondente no porta-chaves secreto\n"
#, fuzzy, c-format
-msgid "valid values for option '%s':\n"
-msgstr "opções de importação inválidas\n"
-
-#, fuzzy, c-format
msgid "unknown TOFU policy '%s'\n"
msgstr "destinatário por omissão desconhecido `%s'\n"
@@ -2234,10 +2241,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr ""
#, fuzzy, c-format
-msgid "invalid value for option '%s'\n"
-msgstr "opções de importação inválidas\n"
-
-#, fuzzy, 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"
@@ -2382,9 +2385,6 @@ msgstr "a escrever chave privada para `%s'\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "o algoritmo de cifragem selecionado é inválido\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "o algoritmo de \"digest\" selecionado é inválido\n"
-
#, fuzzy
msgid "selected compression algorithm is invalid\n"
msgstr "o algoritmo de cifragem selecionado é inválido\n"
@@ -2435,15 +2435,11 @@ 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 "digest algorithm '%s' may not be used 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"
-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 "compression algorithm '%s' may not be used in %s mode\n"
msgstr "não pode utilizar %s enquanto estiver no modo %s\n"
#, c-format
@@ -2462,14 +2458,14 @@ msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "não pode utilizar %s enquanto estiver no modo %s\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "não pode utilizar %s enquanto estiver no modo %s\n"
#, fuzzy, c-format
@@ -2600,6 +2596,10 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr ""
+#, fuzzy
+msgid "repair keys on import"
+msgstr "mostra impressão digital"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "ignorando bloco do tipo %d\n"
@@ -2990,59 +2990,6 @@ msgstr "[revogação]"
msgid "[self-signature]"
msgstr "[auto-assinatura]"
-#, fuzzy, c-format
-msgid "error allocating memory: %s\n"
-msgstr "erro ao criar porta-chaves `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "chave %08lX: algoritmo de chave pública não suportado\n"
-
-#, fuzzy, c-format
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "assinatura %s de: \"%s\"\n"
-
-#, fuzzy
-msgid " (reordered signatures follow)"
-msgstr "Assinatura correcta de \""
-
-#, fuzzy, c-format
-msgid "key %s:\n"
-msgstr "ignorado `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "Utilizador \"%s\" está revocado."
-msgstr[1] "Utilizador \"%s\" está revocado."
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "1 assinatura não verificada por falta de chave\n"
-msgstr[1] "1 assinatura não verificada por falta de chave\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d assinaturas incorrectas\n"
-msgstr[1] "%d assinaturas incorrectas\n"
-
-#, fuzzy, c-format
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "Assinatura correcta de \""
-msgstr[1] "Assinatura correcta de \""
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
#, fuzzy
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
@@ -3576,6 +3523,14 @@ msgstr "Nada para assinar com a chave %08lX\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "%s não é um conjunto de caracteres válido\n"
+#, fuzzy, c-format
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "%s: versão de ficheiro inválida %d\n"
+
+#, fuzzy, c-format
+msgid "subkey \"%s\" not found\n"
+msgstr "chave `%s' não encontrada: %s\n"
+
msgid "Digest: "
msgstr "'Digest': "
@@ -3908,6 +3863,10 @@ msgstr ""
"A mostrar a fotografia %s com o tamanho %ld da chave 0x%08lX (uid %d)\n"
#, fuzzy, c-format
+msgid "invalid value for option '%s'\n"
+msgstr "opções de importação inválidas\n"
+
+#, fuzzy, c-format
msgid "preference '%s' duplicated\n"
msgstr "preferência %c%lu duplicada\n"
@@ -4402,6 +4361,20 @@ msgstr[0] "%d assinaturas incorrectas\n"
msgstr[1] "%d assinaturas incorrectas\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d assinaturas incorrectas\n"
+msgstr[1] "%d assinaturas incorrectas\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "1 assinatura não verificada por falta de chave\n"
+msgstr[1] "1 assinatura não verificada por falta de chave\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4683,6 +4656,11 @@ msgid " aka \"%s\""
msgstr " ou \""
#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr "AVISO: Esta chave não está certificada com uma assinatura confiável!\n"
+
+#, fuzzy, c-format
msgid "Signature expired %s\n"
msgstr "Esta assinatura expirou em %s.\n"
@@ -5241,6 +5219,10 @@ msgid "can't open signed data fd=%d: %s\n"
msgstr "impossível abrir dados assinados `%s'\n"
#, fuzzy, c-format
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "chave %08lX: sem ID de utilizador\n"
+
+#, fuzzy, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "destinatário anónimo; a tentar chave secreta %08lX ...\n"
@@ -5411,6 +5393,11 @@ msgstr ""
msgid "WARNING: signature digest conflict in message\n"
msgstr "AVISO: conflito no 'digest' de assinatura da mensagem\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "não pode utilizar %s enquanto estiver no modo %s\n"
+
#, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr ""
@@ -8195,6 +8182,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr ""
#, fuzzy, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "erro na leitura de `%s': %s\n"
+
+#, fuzzy, c-format
+msgid "error allocating memory: %s\n"
+msgstr "erro ao criar porta-chaves `%s': %s\n"
+
+#, fuzzy, c-format
msgid "error printing log line: %s\n"
msgstr "erro na escrita do porta-chaves `%s': %s\n"
@@ -8302,10 +8297,6 @@ msgid "error reading HTTP response for '%s': %s\n"
msgstr "erro na leitura de `%s': %s\n"
#, fuzzy, c-format
-msgid "error accessing '%s': http status %u\n"
-msgstr "erro na leitura de `%s': %s\n"
-
-#, fuzzy, c-format
msgid "error parsing OCSP response for '%s': %s\n"
msgstr "erro ao enviar para `%s': %s\n"
@@ -8923,6 +8914,36 @@ msgid ""
msgstr ""
#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "chave %08lX: algoritmo de chave pública não suportado\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "assinatura %s de: \"%s\"\n"
+
+#, fuzzy
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "Assinatura correcta de \""
+
+#, fuzzy
+#~ msgid "key %s:\n"
+#~ msgstr "ignorado `%s': %s\n"
+
+#, fuzzy
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "Utilizador \"%s\" está revocado."
+#~ msgstr[1] "Utilizador \"%s\" está revocado."
+
+#, fuzzy
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "Assinatura correcta de \""
+#~ msgstr[1] "Assinatura correcta de \""
+
+#, fuzzy
#~| msgid "new configuration file `%s' created\n"
#~ msgid "new configuration file '%s' created\n"
#~ msgstr "criado um novo ficheiro de configuração `%s'\n"
diff --git a/po/ro.po b/po/ro.po
index 82138a4..0cf134b 100644
--- a/po/ro.po
+++ b/po/ro.po
@@ -406,6 +406,9 @@ msgstr ""
msgid "enable ssh support"
msgstr "nu este suportat(ă)"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable putty support"
@@ -431,6 +434,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr ""
+msgid "selected digest algorithm is invalid\n"
+msgstr "algoritm rezumat selectat este invalid\n"
+
#, fuzzy, c-format
#| msgid "NOTE: no default option file `%s'\n"
msgid "Note: no default option file '%s'\n"
@@ -1299,6 +1305,11 @@ msgstr ""
msgid "WARNING: %s\n"
msgstr "AVERTISMENT: "
+#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s nu merge încă cu %s!\n"
+
#, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "cardul OpenPGP nu e disponibil: %s\n"
@@ -1361,10 +1372,6 @@ msgstr "Eroare: Nume combinat prea lung (limita este de %d caractere).\n"
msgid "URL to retrieve public key: "
msgstr "URL pentru a aduce cheia publică: "
-#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr "Eroare: URL prea lung (limita este de %d caractere).\n"
-
#, fuzzy, c-format
#| msgid "error reading `%s': %s\n"
msgid "error reading '%s': %s\n"
@@ -1377,17 +1384,9 @@ msgstr "eroare la scrierea inelului de chei `%s': %s\n"
msgid "Login data (account name): "
msgstr "Date login (nume cont): "
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr "Eroare: datele de login prea lungi (limita este de %d caractere).\n"
-
msgid "Private DO data: "
msgstr "Date DO personale: "
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr "Eroare DO personal pre lung (limita este de %d caractere).\n"
-
msgid "Language preferences: "
msgstr "Preferinţe limbă: "
@@ -1680,6 +1679,15 @@ msgstr ""
"AVERTISMENT: forţând cifrul simetric %s (%d) violaţi preferinţele "
"destinatarului\n"
+#, fuzzy, c-format
+#| msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "nu puteţi folosi algoritmul de cifrare `%s' câtă vreme în modul %s\n"
+
+#, fuzzy, c-format
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "AVERTISMENT: \"%s\" este o opţiune învechită\n"
+
#, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
@@ -1696,8 +1704,9 @@ msgstr "forţând cifrul simetric %s (%d) violaţi preferinţele destinatarului\
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s cifrat pentru: \"%s\"\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "nu puteţi folosi %s câtă vreme în modul %s\n"
#, c-format
@@ -1872,6 +1881,10 @@ msgstr "Cheia invalidă %s făcută validă de --allow-non-selfsigned-uid\n"
msgid "using subkey %s instead of primary key %s\n"
msgstr "folosim subcheia %s în loc de cheia primară %s\n"
+#, fuzzy, c-format
+msgid "valid values for option '%s':\n"
+msgstr "opţiuni enumerare invalide\n"
+
#, fuzzy
msgid "make a signature"
msgstr "|[fişier]|crează o semnătură"
@@ -2253,10 +2266,6 @@ msgid "show expiration dates during signature listings"
msgstr "Nici o semnătură corespunzătoare în inelul secret\n"
#, fuzzy, c-format
-msgid "valid values for option '%s':\n"
-msgstr "opţiuni enumerare invalide\n"
-
-#, fuzzy, c-format
#| msgid "unknown option `%s'\n"
msgid "unknown TOFU policy '%s'\n"
msgstr "opţiune necunoscută `%s'\n"
@@ -2265,10 +2274,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr ""
#, fuzzy, c-format
-msgid "invalid value for option '%s'\n"
-msgstr "opţiuni enumerare invalide\n"
-
-#, fuzzy, 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"
@@ -2413,9 +2418,6 @@ msgstr "nu va rula cu memorie neprotejată (insecure) pentru că %s\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "algoritm cifrare selectat este invalid\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "algoritm rezumat selectat este invalid\n"
-
msgid "selected compression algorithm is invalid\n"
msgstr "algoritm compresie selectat este invalid\n"
@@ -2462,18 +2464,13 @@ msgid "%s does not yet work with %s\n"
msgstr "%s nu merge încă cu %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 "nu puteţi folosi algoritmul de cifrare `%s' câtă vreme în modul %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"
+msgid "digest algorithm '%s' may not be used in %s mode\n"
msgstr "nu puteţi folosi algorimul de rezumat `%s' câtă vreme în modul %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"
+msgid "compression algorithm '%s' may not be used in %s mode\n"
msgstr "nu puteţi folosi algoritmul de compresie `%s' câtă vreme în modul %s\n"
#, c-format
@@ -2493,15 +2490,17 @@ msgstr "cifrarea simetrică a lui `%s' a eşuat: %s\n"
msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr "nu puteţi folosi --symmetric --encrypt cu --s2k-mode 0\n"
-#, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "nu puteţi folosi --symmetric --encrypt câtă vreme în modul %s\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr "nu puteţi folosi --symmetric --sign --encrypt cu --s2k-mode 0\n"
-#, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "nu puteţi folosi --symmetric --sign --encrypt câtă vreme în modul %s\n"
#, c-format
@@ -2632,6 +2631,11 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr ""
+#, fuzzy
+#| msgid "show key fingerprint"
+msgid "repair keys on import"
+msgstr "afişează amprenta cheii"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "bloc de tip %d sărit\n"
@@ -3025,62 +3029,6 @@ msgstr "[revocare]"
msgid "[self-signature]"
msgstr "[auto-semnătură]"
-#, fuzzy, c-format
-msgid "error allocating memory: %s\n"
-msgstr "eroare la crearea inelului de chei `%s': %s\n"
-
-#, fuzzy, c-format
-#| msgid "key %s: unsupported public key algorithm\n"
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "cheia %s: algoritm cu cheie publică nesuportat\n"
-
-#, fuzzy, c-format
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "semnătură %s, algoritm rezumat %s\n"
-
-#, fuzzy
-#| msgid "revoke signatures"
-msgid " (reordered signatures follow)"
-msgstr "revocă semnături"
-
-#, fuzzy, c-format
-#| msgid "skipped \"%s\": %s\n"
-msgid "key %s:\n"
-msgstr "sărită \"%s\": %s\n"
-
-#, fuzzy, c-format
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "ID utilizator \"%s\" a fost revocat."
-msgstr[1] "ID utilizator \"%s\" a fost revocat."
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "1 semnătură nu a fost verificată din cauza unei chei lipsă\n"
-msgstr[1] "1 semnătură nu a fost verificată din cauza unei chei lipsă\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d semnături incorecte\n"
-msgstr[1] "%d semnături incorecte\n"
-
-#, fuzzy, c-format
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "Semnătură bună din \"%s\""
-msgstr[1] "Semnătură bună din \"%s\""
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
"keys\n"
@@ -3582,6 +3530,16 @@ msgstr "Nimic de semnat cu cheia %s\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "`%s' nu este expirare de semnătură validă\n"
+#, fuzzy, c-format
+#| msgid "invalid fingerprint"
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "amprentă invalidă"
+
+#, fuzzy, c-format
+#| msgid "key \"%s\" not found: %s\n"
+msgid "subkey \"%s\" not found\n"
+msgstr "cheia \"%s\" nu a fost găsită: %s\n"
+
msgid "Digest: "
msgstr "Rezumat: "
@@ -3917,6 +3875,10 @@ 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"
#, fuzzy, c-format
+msgid "invalid value for option '%s'\n"
+msgstr "opţiuni enumerare invalide\n"
+
+#, fuzzy, c-format
#| msgid "preference `%s' duplicated\n"
msgid "preference '%s' duplicated\n"
msgstr "preferinţa `%s' duplicată\n"
@@ -4405,6 +4367,20 @@ msgstr[0] "%d semnături incorecte\n"
msgstr[1] "%d semnături incorecte\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d semnături incorecte\n"
+msgstr[1] "%d semnături incorecte\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "1 semnătură nu a fost verificată din cauza unei chei lipsă\n"
+msgstr[1] "1 semnătură nu a fost verificată din cauza unei chei lipsă\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4684,6 +4660,12 @@ msgstr "[nesigur]"
msgid " aka \"%s\""
msgstr " aka \"%s\""
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr ""
+"AVERTISMENT: Această cheie nu este certificată de o semnătură de încredere!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "Semnătură expirată %s\n"
@@ -5255,6 +5237,10 @@ msgstr "nu pot deschide date semnate `%s'\n"
msgid "can't open signed data fd=%d: %s\n"
msgstr "nu pot deschide date semnate `%s'\n"
+#, fuzzy, c-format
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "cheia %s nu are nici un ID utilizator\n"
+
#, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "destinator anonim; încerc cheia secretă %s ...\n"
@@ -5429,6 +5415,11 @@ msgstr ""
msgid "WARNING: signature digest conflict in message\n"
msgstr "AVERTISMENT: conflict pentru rezumat semnătură în mesaj\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "nu puteţi folosi %s câtă vreme în modul %s\n"
+
#, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr ""
@@ -8259,6 +8250,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr ""
#, fuzzy, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "eroare la citire `%s': %s\n"
+
+#, fuzzy, c-format
+msgid "error allocating memory: %s\n"
+msgstr "eroare la crearea inelului de chei `%s': %s\n"
+
+#, fuzzy, c-format
msgid "error printing log line: %s\n"
msgstr "eroare la scrierea inelului de chei `%s': %s\n"
@@ -8369,10 +8368,6 @@ msgid "error reading HTTP response for '%s': %s\n"
msgstr "eroare la citire `%s': %s\n"
#, fuzzy, c-format
-msgid "error accessing '%s': http status %u\n"
-msgstr "eroare la citire `%s': %s\n"
-
-#, fuzzy, c-format
msgid "error parsing OCSP response for '%s': %s\n"
msgstr "eroare trimitere la `%s': %s\n"
@@ -8993,6 +8988,48 @@ msgid ""
"Check a passphrase given on stdin against the patternfile\n"
msgstr ""
+#~ msgid "Error: URL too long (limit is %d characters).\n"
+#~ msgstr "Eroare: URL prea lung (limita este de %d caractere).\n"
+
+#~ msgid "Error: Login data too long (limit is %d characters).\n"
+#~ msgstr "Eroare: datele de login prea lungi (limita este de %d caractere).\n"
+
+#~ msgid "Error: Private DO too long (limit is %d characters).\n"
+#~ msgstr "Eroare DO personal pre lung (limita este de %d caractere).\n"
+
+#, fuzzy
+#~| msgid "key %s: unsupported public key algorithm\n"
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "cheia %s: algoritm cu cheie publică nesuportat\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "semnătură %s, algoritm rezumat %s\n"
+
+#, fuzzy
+#~| msgid "revoke signatures"
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "revocă semnături"
+
+#, fuzzy
+#~| msgid "skipped \"%s\": %s\n"
+#~ msgid "key %s:\n"
+#~ msgstr "sărită \"%s\": %s\n"
+
+#, fuzzy
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "ID utilizator \"%s\" a fost revocat."
+#~ msgstr[1] "ID utilizator \"%s\" a fost revocat."
+
+#, fuzzy
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "Semnătură bună din \"%s\""
+#~ msgstr[1] "Semnătură bună din \"%s\""
+
#, fuzzy
#~| msgid "new configuration file `%s' created\n"
#~ msgid "new configuration file '%s' created\n"
diff --git a/po/ru.po b/po/ru.po
index bc025f7..8cca5f2 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -380,6 +380,9 @@ msgstr "разрешить ввод фразы-пароля через Emacs"
msgid "enable ssh support"
msgstr "включить поддержку ssh"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
msgid "enable putty support"
msgstr "включить поддержку putty"
@@ -403,6 +406,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr "запрошен недопустимый уровень отладки '%s'\n"
+msgid "selected digest algorithm is invalid\n"
+msgstr "выбрана недопустимая хеш-функция\n"
+
#, c-format
msgid "Note: no default option file '%s'\n"
msgstr "Замечание: основной файл параметров '%s' не обнаружен\n"
@@ -1204,6 +1210,11 @@ msgstr "сервер '%s' старше нас (%s < %s)"
msgid "WARNING: %s\n"
msgstr "Внимание: %s\n"
+#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s пока не работает совместно с %s!\n"
+
#, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "Карта OpenPGP недоступна: %s\n"
@@ -1265,10 +1276,6 @@ msgid "URL to retrieve public key: "
msgstr "URL для получения открытого ключа: "
#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr "Ошибка: Слишком длинный URL (предел - %d символов).\n"
-
-#, c-format
msgid "error reading '%s': %s\n"
msgstr "ошибка чтения '%s': %s\n"
@@ -1279,18 +1286,9 @@ msgstr "ошибка записи '%s': %s\n"
msgid "Login data (account name): "
msgstr "Учетная запись (имя): "
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr ""
-"Ошибка: Слишком длинные данные учетной записи (предел - %d символов).\n"
-
msgid "Private DO data: "
msgstr "Секретные данные DO:"
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr "Ошибка: Слишком много секретных данных DO (предел - %d символов).\n"
-
msgid "Language preferences: "
msgstr "Предпочтительный язык: "
@@ -1567,6 +1565,16 @@ msgstr ""
"Внимание: принудительное использование симметричного шифра %s (%d)\n"
" нарушает предпочтения получателя\n"
+#, fuzzy, c-format
+#| msgid "you may not use cipher algorithm '%s' while in %s mode\n"
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "шифрование '%s' в режиме %s использовать нельзя\n"
+
+#, fuzzy, c-format
+#| msgid "WARNING: \"%s%s\" is an obsolete option - it has no effect\n"
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "Внимание: параметр \"%s%s\" устарел - он игнорируется\n"
+
#, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
@@ -1583,8 +1591,9 @@ msgstr ""
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s зашифровано для пользователя \"%s\"\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "нельзя использовать %s в режиме %s\n"
#, c-format
@@ -1750,6 +1759,10 @@ msgstr ""
msgid "using subkey %s instead of primary key %s\n"
msgstr "использую подключ %s вместо первичного ключа %s\n"
+#, c-format
+msgid "valid values for option '%s':\n"
+msgstr "недопустимые значения для параметра \"%s\"\n"
+
msgid "make a signature"
msgstr "создать подпись"
@@ -2069,10 +2082,6 @@ msgid "show expiration dates during signature listings"
msgstr "показать в списке подписей сроки действия"
#, c-format
-msgid "valid values for option '%s':\n"
-msgstr "недопустимые значения для параметра \"%s\"\n"
-
-#, c-format
msgid "unknown TOFU policy '%s'\n"
msgstr "неизвестные правила TOFU '%s'\n"
@@ -2080,10 +2089,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr "(\"help\" выведет список вариантов)\n"
#, c-format
-msgid "invalid value for option '%s'\n"
-msgstr "недопустимое значения для параметра \"%s\"\n"
-
-#, c-format
msgid "Note: old default options file '%s' ignored\n"
msgstr "Замечание: старый основной файл параметров '%s' проигнорирован\n"
@@ -2222,9 +2227,6 @@ msgstr "не будет работать с небезопасной памят
msgid "selected cipher algorithm is invalid\n"
msgstr "выбран недопустимый алгоритм шифрования\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "выбрана недопустимая хеш-функция\n"
-
msgid "selected compression algorithm is invalid\n"
msgstr "выбран недопустимый алгоритм сжатия\n"
@@ -2268,16 +2270,14 @@ msgstr "недопустимые личные предпочтения алго
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"
-
-#, c-format
-msgid "you may not use digest algorithm '%s' while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use digest algorithm '%s' while in %s mode\n"
+msgid "digest algorithm '%s' may not be used in %s mode\n"
msgstr "хеш-функцию '%s' в режиме %s использовать нельзя\n"
-#, c-format
-msgid "you may not use compression algorithm '%s' while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use compression algorithm '%s' while in %s mode\n"
+msgid "compression algorithm '%s' may not be used in %s mode\n"
msgstr "сжатие '%s' в режиме %s использовать нельзя\n"
#, c-format
@@ -2296,16 +2296,18 @@ msgstr "сбой симметричного шифрования '%s': %s\n"
msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr "--symmetric --encrypt нельзя использовать совместно с --s2k-mode 0\n"
-#, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "в режиме %s нельзя использовать --symmetric --encrypt\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr ""
"нельзя использовать --symmetric --sign --encrypt совместно с --s2k-mode 0\n"
-#, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "в режиме %s нельзя использовать --symmetric --sign --encrypt\n"
#, c-format
@@ -2426,6 +2428,11 @@ msgstr "применить фильтры импорта и немедленно
msgid "assume the GnuPG key backup format"
msgstr "ожидать ключи в архивном формате GnuPG"
+#, fuzzy
+#| msgid "show key during import"
+msgid "repair keys on import"
+msgstr "показывать ключ во время импорта"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "пропущен блок типа %d\n"
@@ -2812,64 +2819,6 @@ msgstr "[отзыв]"
msgid "[self-signature]"
msgstr "[самоподпись]"
-#, c-format
-msgid "error allocating memory: %s\n"
-msgstr "ошибка выделения памяти: %s\n"
-
-#, c-format
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr ""
-"не удалось проверить подпись: алгоритм с открытым ключом %d не "
-"поддерживается: %s.\n"
-
-#, c-format
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "не удалось проверить подпись: хеш-функция %d не поддерживается: %s.\n"
-
-msgid " (reordered signatures follow)"
-msgstr "(порядок подписей изменен)"
-
-#, c-format
-msgid "key %s:\n"
-msgstr "ключ %s:\n"
-
-#, c-format
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "%d повторная подпись удалена\n"
-msgstr[1] "%d повторные подписи удалены\n"
-msgstr[2] "%d повторных подписей удалено\n"
-
-#, c-format
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "%d подпись не проверена за отсутствием ключа\n"
-msgstr[1] "%d подписи не проверены за отсутствием ключа\n"
-msgstr[2] "%d подписей не проверено за отсутствием ключа\n"
-
-#, c-format
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d плохая подпись\n"
-msgstr[1] "%d плохих подписи\n"
-msgstr[2] "%d плохих подписей\n"
-
-#, c-format
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "Порядок %d подписи изменен\n"
-msgstr[1] "Порядок %d подписей изменен\n"
-msgstr[2] "Порядок %d подписей изменен\n"
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-"Внимание: обнаружены ошибки, проверялись только самоподписи; для проверки "
-"всех подписей выполните '%s'.\n"
-
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
"keys\n"
@@ -3352,6 +3301,16 @@ msgstr "Подписывать нечего.\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "'%s' - не допустимый срок действия\n"
+#, fuzzy, c-format
+#| msgid "\"%s\" is not a fingerprint\n"
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "\"%s\" - не отпечаток\n"
+
+#, fuzzy, c-format
+#| msgid "key \"%s\" not found\n"
+msgid "subkey \"%s\" not found\n"
+msgstr "ключ \"%s\" не найден\n"
+
msgid "Digest: "
msgstr "Хеш: "
@@ -3676,6 +3635,10 @@ msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
msgstr "Показ фотоидентификатора %s размера %ld для ключа %s (uid %d)\n"
#, c-format
+msgid "invalid value for option '%s'\n"
+msgstr "недопустимое значения для параметра \"%s\"\n"
+
+#, c-format
msgid "preference '%s' duplicated\n"
msgstr "предпочтение '%s' дублируется\n"
@@ -4146,6 +4109,20 @@ msgstr[1] "%d хороших подписи\n"
msgstr[2] "%d хороших подписей\n"
#, c-format
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d плохая подпись\n"
+msgstr[1] "%d плохих подписи\n"
+msgstr[2] "%d плохих подписей\n"
+
+#, c-format
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "%d подпись не проверена за отсутствием ключа\n"
+msgstr[1] "%d подписи не проверены за отсутствием ключа\n"
+msgstr[2] "%d подписей не проверено за отсутствием ключа\n"
+
+#, c-format
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
msgstr[0] "%d подпись не проверена из-за ошибки\n"
@@ -4417,6 +4394,11 @@ msgstr "[сомнительно]"
msgid " aka \"%s\""
msgstr " или \"%s\""
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr "Внимание: Данный ключ не заверен доверенной подписью!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "Подпись просрочена %s\n"
@@ -4951,6 +4933,11 @@ msgstr "не могу открыть подписанные данные '%s'\n"
msgid "can't open signed data fd=%d: %s\n"
msgstr "не могу открыть подписанные данные fd=%d: %s\n"
+#, fuzzy, c-format
+#| msgid "certificate is not usable for encryption\n"
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "сертификат не пригоден для шифрования\n"
+
#, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "анонимный получатель; пробую секретный ключ %s ...\n"
@@ -5126,6 +5113,11 @@ msgstr "Ключ %s %s требует %zu-битного или более дл
msgid "WARNING: signature digest conflict in message\n"
msgstr "Внимание: конфликт хешей подписей в сообщении\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "нельзя использовать %s в режиме %s\n"
+
#, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr "Внимание: подписывающий подключ %s не был перекрестно заверен\n"
@@ -7895,6 +7887,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr "'%s' - недопустимый URL LDAP\n"
#, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "ошибка чтения '%s': статус HTTP %u\n"
+
+#, c-format
+msgid "error allocating memory: %s\n"
+msgstr "ошибка выделения памяти: %s\n"
+
+#, c-format
msgid "error printing log line: %s\n"
msgstr "ошибка вывода строки журнала: %s\n"
@@ -7998,10 +7998,6 @@ 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"
@@ -8595,6 +8591,52 @@ msgstr ""
"Синтаксис: gpg-check-pattern [параметры] файл_образцов\n"
"Проверить фразу-пароль, поступающую из stdin, по файлу образцов\n"
+#~ msgid "Error: URL too long (limit is %d characters).\n"
+#~ msgstr "Ошибка: Слишком длинный URL (предел - %d символов).\n"
+
+#~ msgid "Error: Login data too long (limit is %d characters).\n"
+#~ msgstr ""
+#~ "Ошибка: Слишком длинные данные учетной записи (предел - %d символов).\n"
+
+#~ msgid "Error: Private DO too long (limit is %d characters).\n"
+#~ msgstr "Ошибка: Слишком много секретных данных DO (предел - %d символов).\n"
+
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr ""
+#~ "не удалось проверить подпись: алгоритм с открытым ключом %d не "
+#~ "поддерживается: %s.\n"
+
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr ""
+#~ "не удалось проверить подпись: хеш-функция %d не поддерживается: %s.\n"
+
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "(порядок подписей изменен)"
+
+#~ msgid "key %s:\n"
+#~ msgstr "ключ %s:\n"
+
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "%d повторная подпись удалена\n"
+#~ msgstr[1] "%d повторные подписи удалены\n"
+#~ msgstr[2] "%d повторных подписей удалено\n"
+
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "Порядок %d подписи изменен\n"
+#~ msgstr[1] "Порядок %d подписей изменен\n"
+#~ msgstr[2] "Порядок %d подписей изменен\n"
+
+#~ msgid ""
+#~ "Warning: errors found and only checked self-signatures, run '%s' to check "
+#~ "all signatures.\n"
+#~ msgstr ""
+#~ "Внимание: обнаружены ошибки, проверялись только самоподписи; для проверки "
+#~ "всех подписей выполните '%s'.\n"
+
#~ msgid ", "
#~ msgstr ", "
diff --git a/po/sk.po b/po/sk.po
index fb3e686..6aaf628 100644
--- a/po/sk.po
+++ b/po/sk.po
@@ -394,6 +394,9 @@ msgstr ""
msgid "enable ssh support"
msgstr "nepodporované"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable putty support"
@@ -421,6 +424,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr ""
+msgid "selected digest algorithm is invalid\n"
+msgstr "vybraný hashovací algoritmus je neplatný\n"
+
#, fuzzy, c-format
#| msgid "NOTE: no default option file `%s'\n"
msgid "Note: no default option file '%s'\n"
@@ -1283,6 +1289,11 @@ msgid "WARNING: %s\n"
msgstr "VAROVANIE: %s prepíše %s\n"
#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s ešte nepracuje s %s\n"
+
+#, fuzzy, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "tajný kľúč nie je dostupný"
@@ -1350,10 +1361,6 @@ msgstr ""
msgid "URL to retrieve public key: "
msgstr "žiadny zodpovedajúci verejný kľúč: %s\n"
-#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy, c-format
#| msgid "error reading `%s': %s\n"
msgid "error reading '%s': %s\n"
@@ -1366,17 +1373,9 @@ msgstr "chyba pri zápise súboru kľúčov (keyring) `%s': %s\n"
msgid "Login data (account name): "
msgstr ""
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr ""
-
msgid "Private DO data: "
msgstr ""
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr ""
-
#, fuzzy
msgid "Language preferences: "
msgstr "aktualizovať predvoľby"
@@ -1680,6 +1679,14 @@ msgid ""
msgstr "vyžiadaná symetrická šifra %s (%d) nevyhovuje predvoľbám príjemcu\n"
#, fuzzy, c-format
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "nemôžete použiť šifrovací algoritmus \"%s\" v móde %s\n"
+
+#, fuzzy, c-format
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "VAROVÁNÍ: použitie parametra \"%s\" sa neodporúča\n"
+
+#, fuzzy, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
"preferences\n"
@@ -1694,8 +1701,9 @@ msgstr "vyžiadaná symetrická šifra %s (%d) nevyhovuje predvoľbám príjemcu
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s zašifrovaný pre: %s\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr ""
"použitie %s nie je v móde %s dovolené\n"
"\n"
@@ -1876,6 +1884,10 @@ msgstr ""
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 "valid values for option '%s':\n"
+msgstr "neplatný parameter pre import\n"
+
#, fuzzy
msgid "make a signature"
msgstr "vytvoriť podpis oddelený od dokumentu"
@@ -2233,10 +2245,6 @@ msgid "show expiration dates during signature listings"
msgstr "V súbore tajných kľúčov chýba zodpovedajúci podpis\n"
#, fuzzy, c-format
-msgid "valid values for option '%s':\n"
-msgstr "neplatný parameter pre import\n"
-
-#, fuzzy, c-format
msgid "unknown TOFU policy '%s'\n"
msgstr "neznámy implicitný adresát `%s'\n"
@@ -2244,10 +2252,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr ""
#, fuzzy, c-format
-msgid "invalid value for option '%s'\n"
-msgstr "neplatný parameter pre import\n"
-
-#, fuzzy, 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"
@@ -2392,9 +2396,6 @@ msgstr "zapisujem tajný kľúč do `%s'\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "vybraný šifrovací algoritmus je neplatný\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "vybraný hashovací algoritmus je neplatný\n"
-
#, fuzzy
msgid "selected compression algorithm is invalid\n"
msgstr "vybraný šifrovací algoritmus je neplatný\n"
@@ -2443,15 +2444,11 @@ 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"
-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 "digest algorithm '%s' may not be used 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 "compression algorithm '%s' may not be used in %s mode\n"
msgstr "nemôžete použiť kompresný algoritmus \"%s\" v móde %s\n"
#, c-format
@@ -2470,7 +2467,7 @@ msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr ""
"použitie %s nie je v móde %s dovolené\n"
"\n"
@@ -2479,7 +2476,7 @@ msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr ""
#, fuzzy, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr ""
"použitie %s nie je v móde %s dovolené\n"
"\n"
@@ -2612,6 +2609,10 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr ""
+#, fuzzy
+msgid "repair keys on import"
+msgstr "vypísať fingerprint"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "blok typu %d bol preskočený\n"
@@ -3004,59 +3005,6 @@ msgstr "[revokácia]"
msgid "[self-signature]"
msgstr "[podpis kľúča ním samým]"
-#, fuzzy, c-format
-msgid "error allocating memory: %s\n"
-msgstr "chyba pri vytváraní súboru kľúčov (keyring)`%s': %s\n"
-
-#, fuzzy, c-format
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "kľúč %08lX: nepodporovaný algoritmus verejného kľúča\n"
-
-#, fuzzy, c-format
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "%s podpis, hashovací algoritmus %s\n"
-
-#, fuzzy
-msgid " (reordered signatures follow)"
-msgstr "Dobrý podpis od \""
-
-#, fuzzy, c-format
-msgid "key %s:\n"
-msgstr "preskočený `%s': %s\n"
-
-#, fuzzy, c-format
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "Užívateľské ID \"%s\" je revokované."
-msgstr[1] "Užívateľské ID \"%s\" je revokované."
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "1 podpis neoverený, pretože chýba kľúč\n"
-msgstr[1] "1 podpis neoverený, pretože chýba kľúč\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d zlých podpisov\n"
-msgstr[1] "%d zlých podpisov\n"
-
-#, fuzzy, c-format
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "Dobrý podpis od \""
-msgstr[1] "Dobrý podpis od \""
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
#, fuzzy
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
@@ -3587,6 +3535,14 @@ msgstr "Nič na podpísanie kľúčom %08lX\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "%s nie je platná znaková sada\n"
+#, fuzzy, c-format
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "chyba: neplatný odtlačok\n"
+
+#, fuzzy, c-format
+msgid "subkey \"%s\" not found\n"
+msgstr "kľúč `%s' nebol nájdený: %s\n"
+
msgid "Digest: "
msgstr "Digest: "
@@ -3918,6 +3874,10 @@ msgstr ""
"Zobrazujem %s fotografické ID s veľkosťou %ld pre kľúč 0x%08lX (uid %d)\n"
#, fuzzy, c-format
+msgid "invalid value for option '%s'\n"
+msgstr "neplatný parameter pre import\n"
+
+#, fuzzy, c-format
msgid "preference '%s' duplicated\n"
msgstr "duplicita predvoľby %c%lu\n"
@@ -4407,6 +4367,20 @@ msgstr[0] "%d zlých podpisov\n"
msgstr[1] "%d zlých podpisov\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d zlých podpisov\n"
+msgstr[1] "%d zlých podpisov\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "1 podpis neoverený, pretože chýba kľúč\n"
+msgstr[1] "1 podpis neoverený, pretože chýba kľúč\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4692,6 +4666,11 @@ msgstr "[neistý] "
msgid " aka \"%s\""
msgstr " alias \""
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr "VAROVANIE: Tento kľúč nie certifikovaný dôveryhodným podpisom!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "Platnosť podpisu vypršala %s\n"
@@ -5250,6 +5229,10 @@ msgid "can't open signed data fd=%d: %s\n"
msgstr "nemôžem otvoriť podpísané dáta '%s'\n"
#, fuzzy, c-format
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "kľúč %08lX: chyba identifikátor užívateľa\n"
+
+#, fuzzy, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "anonymný adresát; skúšam tajný kľúč %08lX ...\n"
@@ -5424,6 +5407,13 @@ msgid "WARNING: signature digest conflict in message\n"
msgstr "VAROVANIE: konflikt hashu podpisu v správe\n"
#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr ""
+"použitie %s nie je v móde %s dovolené\n"
+"\n"
+
+#, fuzzy, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr "VAROVANIE: podpisovací podkľúč %08lX nie je krížovo certifikovaný\n"
@@ -8214,6 +8204,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr ""
#, fuzzy, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "chyba pri čítaní `%s': %s\n"
+
+#, fuzzy, c-format
+msgid "error allocating memory: %s\n"
+msgstr "chyba pri vytváraní súboru kľúčov (keyring)`%s': %s\n"
+
+#, fuzzy, c-format
msgid "error printing log line: %s\n"
msgstr "chyba pri zápise súboru kľúčov (keyring) `%s': %s\n"
@@ -8321,10 +8319,6 @@ msgid "error reading HTTP response for '%s': %s\n"
msgstr "chyba pri čítaní `%s': %s\n"
#, fuzzy, c-format
-msgid "error accessing '%s': http status %u\n"
-msgstr "chyba pri čítaní `%s': %s\n"
-
-#, fuzzy, c-format
msgid "error parsing OCSP response for '%s': %s\n"
msgstr "chyba pri posielaní na `%s': %s\n"
@@ -8942,6 +8936,36 @@ msgid ""
msgstr ""
#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "kľúč %08lX: nepodporovaný algoritmus verejného kľúča\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "%s podpis, hashovací algoritmus %s\n"
+
+#, fuzzy
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "Dobrý podpis od \""
+
+#, fuzzy
+#~ msgid "key %s:\n"
+#~ msgstr "preskočený `%s': %s\n"
+
+#, fuzzy
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "Užívateľské ID \"%s\" je revokované."
+#~ msgstr[1] "Užívateľské ID \"%s\" je revokované."
+
+#, fuzzy
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "Dobrý podpis od \""
+#~ msgstr[1] "Dobrý podpis od \""
+
+#, fuzzy
#~| msgid "new configuration file `%s' created\n"
#~ msgid "new configuration file '%s' created\n"
#~ msgstr "vytvorený nový konfiguračný súbor `%s'\n"
diff --git a/po/sv.po b/po/sv.po
index 1f9ff53..dcd53d1 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -441,6 +441,9 @@ msgstr ""
msgid "enable ssh support"
msgstr "aktivera ssh-agent-emulering"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
msgid "enable putty support"
msgstr ""
@@ -473,6 +476,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr "ogiltig debug-level \"%s\" angiven\n"
+msgid "selected digest algorithm is invalid\n"
+msgstr "vald sammandragsalgoritm är ogiltig\n"
+
#, fuzzy, c-format
#| msgid "NOTE: no default option file `%s'\n"
msgid "Note: no default option file '%s'\n"
@@ -1352,6 +1358,11 @@ msgstr ""
msgid "WARNING: %s\n"
msgstr "VARNING: %s gäller istället för %s\n"
+#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s fungerar ännu inte med %s\n"
+
#, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "OpenPGP-kort är inte tillgängligt: %s\n"
@@ -1412,10 +1423,6 @@ msgstr "Fel: Fullständigt namn för långt (gränsen är %d tecken).\n"
msgid "URL to retrieve public key: "
msgstr "Url för att hämta publik nyckel: "
-#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr "Fel: URL:en är för lång (gränsen är %d tecken).\n"
-
#, fuzzy, c-format
#| msgid "error reading `%s': %s\n"
msgid "error reading '%s': %s\n"
@@ -1429,17 +1436,9 @@ msgstr "fel vid skrivning till \"%s\": %s\n"
msgid "Login data (account name): "
msgstr "Inloggningsdata (kontonamn): "
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr "Fel: Inloggningsdata är för långt (gräns är %d tecken).\n"
-
msgid "Private DO data: "
msgstr "Privat DO-data: "
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr "Fel: Privat DO för långt (gränsen är %d tecken).\n"
-
msgid "Language preferences: "
msgstr "Språkinställningar: "
@@ -1748,6 +1747,16 @@ msgstr ""
"VARNING: tvinga symmetriskt chiffer med %s (%d) strider mot "
"mottagarinställningarna\n"
+#, fuzzy, c-format
+#| msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "du får inte använda chifferalgoritmen \"%s\" när du är i %s-läget\n"
+
+#, fuzzy, c-format
+#| msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "VARNING: \"%s\" är en föråldrad flagga - den har ingen effekt\n"
+
#, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
@@ -1765,8 +1774,9 @@ msgstr ""
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s krypterad för: \"%s\"\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "du kan inte använda %s när du är i %s-läget\n"
#, c-format
@@ -1943,6 +1953,11 @@ msgstr ""
msgid "using subkey %s instead of primary key %s\n"
msgstr "använder undernyckeln %s istället för primära nyckeln %s\n"
+#, fuzzy, c-format
+#| msgid "missing argument for option \"%.50s\"\n"
+msgid "valid values for option '%s':\n"
+msgstr "argument för flaggan \"%.50s\" saknas\n"
+
msgid "make a signature"
msgstr "skapa en signatur"
@@ -2312,11 +2327,6 @@ msgid "show expiration dates during signature listings"
msgstr "visa utgångsdatum under signaturlistningar"
#, fuzzy, c-format
-#| msgid "missing argument for option \"%.50s\"\n"
-msgid "valid values for option '%s':\n"
-msgstr "argument för flaggan \"%.50s\" saknas\n"
-
-#, fuzzy, c-format
#| msgid "unknown option `%s'\n"
msgid "unknown TOFU policy '%s'\n"
msgstr "okänd flagga \"%s\"\n"
@@ -2325,11 +2335,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr ""
#, fuzzy, c-format
-#| msgid "missing argument for option \"%.50s\"\n"
-msgid "invalid value for option '%s'\n"
-msgstr "argument för flaggan \"%.50s\" saknas\n"
-
-#, fuzzy, 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"
@@ -2472,9 +2477,6 @@ msgstr "kommer inte att köra med osäkert minne på grund av %s\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "den valda chifferalgoritmen är ogiltig\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "vald sammandragsalgoritm är ogiltig\n"
-
msgid "selected compression algorithm is invalid\n"
msgstr "vald komprimeringsalgoritm är ogiltig\n"
@@ -2529,19 +2531,14 @@ msgid "%s does not yet work with %s\n"
msgstr "%s fungerar ännu inte med %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 "du får inte använda chifferalgoritmen \"%s\" när du är i %s-läget\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"
+msgid "digest algorithm '%s' may not be used in %s mode\n"
msgstr ""
"du får inte använda sammandragsalgoritmen \"%s\" när du är i %s-läget\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"
+msgid "compression algorithm '%s' may not be used in %s mode\n"
msgstr ""
"du får inte använda komprimeringsalgoritmen \"%s\" när du är i %s-läget\n"
@@ -2561,15 +2558,17 @@ msgstr "symmetrisk kryptering av \"%s\" misslyckades: %s\n"
msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr "du kan inte använda --symmetric --encrypt med --s2k-mode 0\n"
-#, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "du kan inte använda --symmetric --encrypt i %s-läget\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr "du kan inte använda --symmetric --sign --encrypt med --s2k-mode 0\n"
-#, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr ""
"du kan inte använda --symmetric --sign --encrypt när du är i %s-läget\n"
@@ -2704,6 +2703,11 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr "anta att inmatning är i binärformat"
+#, fuzzy
+#| msgid "show key fingerprint"
+msgid "repair keys on import"
+msgstr "visa nyckelns fingeravtryck"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "hoppar över block av typen %d\n"
@@ -3107,66 +3111,6 @@ msgstr "[spärr]"
msgid "[self-signature]"
msgstr "[självsignatur]"
-#, fuzzy, c-format
-#| msgid "error allocating enough memory: %s\n"
-msgid "error allocating memory: %s\n"
-msgstr "fel vid allokering av tillräckligt mycket minne: %s\n"
-
-#, fuzzy, c-format
-#| msgid "key %s: unsupported public key algorithm\n"
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "nyckel %s: algoritmen för publika nycklar stöds inte\n"
-
-#, fuzzy, c-format
-#| msgid "card does not support digest algorithm %s\n"
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "kortet har inte stöd för sammandragsalgoritmen %s\n"
-
-#, fuzzy
-#| msgid "Good signature from"
-msgid " (reordered signatures follow)"
-msgstr "Korrekt signatur från"
-
-#, fuzzy, c-format
-#| msgid "skipped \"%s\": %s\n"
-msgid "key %s:\n"
-msgstr "hoppade över \"%s\": %s\n"
-
-#, fuzzy, c-format
-#| msgid "User ID \"%s\": %d signature removed\n"
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "Användaridentitet \"%s\": %d signaturer borttagna\n"
-msgstr[1] "Användaridentitet \"%s\": %d signaturer borttagna\n"
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "1 signatur validerades inte eftersom nyckeln saknades\n"
-msgstr[1] "1 signatur validerades inte eftersom nyckeln saknades\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d felaktiga signaturer\n"
-msgstr[1] "%d felaktiga signaturer\n"
-
-#, fuzzy, c-format
-#| msgid "Good signature from"
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "Korrekt signatur från"
-msgstr[1] "Korrekt signatur från"
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
"keys\n"
@@ -3672,6 +3616,16 @@ msgstr "Det finns inget att signera med nyckeln %s\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "\"%s\" är inte ett giltigt utgångsdatum för en signatur\n"
+#, fuzzy, c-format
+#| msgid "invalid fingerprint"
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "ogiltigt fingeravtryck"
+
+#, fuzzy, c-format
+#| msgid "key \"%s\" not found: %s\n"
+msgid "subkey \"%s\" not found\n"
+msgstr "nyckeln \"%s\" hittades inte: %s\n"
+
msgid "Digest: "
msgstr "Sammandrag: "
@@ -4007,6 +3961,11 @@ 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"
#, fuzzy, c-format
+#| msgid "missing argument for option \"%.50s\"\n"
+msgid "invalid value for option '%s'\n"
+msgstr "argument för flaggan \"%.50s\" saknas\n"
+
+#, fuzzy, c-format
#| msgid "preference `%s' duplicated\n"
msgid "preference '%s' duplicated\n"
msgstr "inställningen \"%s\" förekommer flera gånger\n"
@@ -4510,6 +4469,20 @@ msgstr[0] "%d felaktiga signaturer\n"
msgstr[1] "%d felaktiga signaturer\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d felaktiga signaturer\n"
+msgstr[1] "%d felaktiga signaturer\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "1 signatur validerades inte eftersom nyckeln saknades\n"
+msgstr[1] "1 signatur validerades inte eftersom nyckeln saknades\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4796,6 +4769,11 @@ msgstr "[osäkert]"
msgid " aka \"%s\""
msgstr " även känd som \"%s\""
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr "VARNING: Denna nyckel är inte certifierad med en pålitlig signatur!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "Giltighetstiden för signaturen har upphört %s\n"
@@ -5375,6 +5353,11 @@ msgstr "kan inte öppna signerat data \"%s\"\n"
msgid "can't open signed data fd=%d: %s\n"
msgstr "kan inte öppna signerad data fd=%d: %s\n"
+#, fuzzy, c-format
+#| msgid "certificate is not usable for encryption\n"
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "certifikatet är inte användbart för kryptering\n"
+
#, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "anonym mottagare; provar med den hemliga nyckeln %s ...\n"
@@ -5559,6 +5542,11 @@ msgstr "DSA-nyckeln %s kräver en hash med %u bitar eller större\n"
msgid "WARNING: signature digest conflict in message\n"
msgstr "VARNING: konflikt mellan signatursammandrag i meddelandet\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "du kan inte använda %s när du är i %s-läget\n"
+
# Vad betyder det?
#, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
@@ -8554,6 +8542,16 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr ""
#, fuzzy, c-format
+#| msgid "error running `%s': exit status %d\n"
+msgid "error accessing '%s': http status %u\n"
+msgstr "fel vid körning av \"%s\": avslutsstatus %d\n"
+
+#, fuzzy, c-format
+#| msgid "error allocating enough memory: %s\n"
+msgid "error allocating memory: %s\n"
+msgstr "fel vid allokering av tillräckligt mycket minne: %s\n"
+
+#, fuzzy, c-format
#| msgid "error writing to %s: %s\n"
msgid "error printing log line: %s\n"
msgstr "fel vid skrivning till %s: %s\n"
@@ -8676,11 +8674,6 @@ msgid "error reading HTTP response for '%s': %s\n"
msgstr "fel vid läsning från %s: %s\n"
#, fuzzy, c-format
-#| msgid "error running `%s': exit status %d\n"
-msgid "error accessing '%s': http status %u\n"
-msgstr "fel vid körning av \"%s\": avslutsstatus %d\n"
-
-#, fuzzy, c-format
#| msgid "error binding socket to `%s': %s\n"
msgid "error parsing OCSP response for '%s': %s\n"
msgstr "fel när \"%s\" bands till uttag: %s\n"
@@ -9354,6 +9347,51 @@ msgstr ""
"Syntax: gpg-check-pattern [flaggor] mönsterfil\n"
"Kontrollera en lösenfras angiven på standard in mot mönsterfilen\n"
+#~ msgid "Error: URL too long (limit is %d characters).\n"
+#~ msgstr "Fel: URL:en är för lång (gränsen är %d tecken).\n"
+
+#~ msgid "Error: Login data too long (limit is %d characters).\n"
+#~ msgstr "Fel: Inloggningsdata är för långt (gräns är %d tecken).\n"
+
+#~ msgid "Error: Private DO too long (limit is %d characters).\n"
+#~ msgstr "Fel: Privat DO för långt (gränsen är %d tecken).\n"
+
+#, fuzzy
+#~| msgid "key %s: unsupported public key algorithm\n"
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "nyckel %s: algoritmen för publika nycklar stöds inte\n"
+
+#, fuzzy
+#~| msgid "card does not support digest algorithm %s\n"
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "kortet har inte stöd för sammandragsalgoritmen %s\n"
+
+#, fuzzy
+#~| msgid "Good signature from"
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "Korrekt signatur från"
+
+#, fuzzy
+#~| msgid "skipped \"%s\": %s\n"
+#~ msgid "key %s:\n"
+#~ msgstr "hoppade över \"%s\": %s\n"
+
+#, fuzzy
+#~| msgid "User ID \"%s\": %d signature removed\n"
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "Användaridentitet \"%s\": %d signaturer borttagna\n"
+#~ msgstr[1] "Användaridentitet \"%s\": %d signaturer borttagna\n"
+
+#, fuzzy
+#~| msgid "Good signature from"
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "Korrekt signatur från"
+#~ msgstr[1] "Korrekt signatur från"
+
#, fuzzy
#~| msgid "new configuration file `%s' created\n"
#~ msgid "new configuration file '%s' created\n"
diff --git a/po/tr.po b/po/tr.po
index b707775..0fa3c40 100644
--- a/po/tr.po
+++ b/po/tr.po
@@ -410,6 +410,9 @@ msgstr ""
msgid "enable ssh support"
msgstr "ssh-agent öykünümü etkinleşir"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
msgid "enable putty support"
msgstr ""
@@ -441,6 +444,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr "belirtilen hata seviyesi `%s' geçersiz\n"
+msgid "selected digest algorithm is invalid\n"
+msgstr "seçilen özet algoritması geçersiz\n"
+
#, fuzzy, c-format
#| msgid "NOTE: no default option file `%s'\n"
msgid "Note: no default option file '%s'\n"
@@ -1316,6 +1322,11 @@ msgstr ""
msgid "WARNING: %s\n"
msgstr "UYARI: %s %s'i aşıyor\n"
+#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s, %s ile henüz çalışmıyor\n"
+
#, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "OpenPGP anahtarı kullanılabilir değil: %s\n"
@@ -1376,10 +1387,6 @@ msgstr "Hata: İsimler birlikte çok uzun oluyor (sınır: %d karakter).\n"
msgid "URL to retrieve public key: "
msgstr "genel anahtarın alınacağı URL: "
-#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr "Hata: URL çok uzun (sınır: %d karakter).\n"
-
#, fuzzy, c-format
#| msgid "error reading `%s': %s\n"
msgid "error reading '%s': %s\n"
@@ -1392,17 +1399,9 @@ msgstr "`%s' yazılırken hata: %s\n"
msgid "Login data (account name): "
msgstr "Oturum açma verisi (hesap adı): "
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr "Hata: Oturum açma verisi çok uzun (sınır: %d karakter).\n"
-
msgid "Private DO data: "
msgstr "Özel DO verisi: "
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr "Hata: Özel DO çok uzun (sınır: %d karakter).\n"
-
msgid "Language preferences: "
msgstr "Dil tercihleri: "
@@ -1695,6 +1694,16 @@ msgstr ""
"UYARI: alıcının tercihleriyle çelişen %s (%d) simetrik şifre kullanımı "
"zorlanıyor\n"
+#, fuzzy, c-format
+#| msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "%2$s kipindeyken '%1$s' şifreleme algoritması kullanılamaz\n"
+
+#, fuzzy, c-format
+#| msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n"
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "UYARI: \"%s\" seçeneği eskidi - artık etkisiz\n"
+
#, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
@@ -1712,8 +1721,9 @@ msgstr ""
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s \"%s\" için şifrelendi\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "%2$s kipindeyken %1$s kullanılamayabilir.\n"
#, c-format
@@ -1888,6 +1898,11 @@ 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"
+#, fuzzy, c-format
+#| msgid "missing argument for option \"%.50s\"\n"
+msgid "valid values for option '%s':\n"
+msgstr "\"%.50s\" seçeneği için değiştirge eksik\n"
+
msgid "make a signature"
msgstr "bir imza yapar"
@@ -2250,11 +2265,6 @@ msgid "show expiration dates during signature listings"
msgstr "imza listelemesi sırasında zamanaşımı tarihleri gösterilir"
#, fuzzy, c-format
-#| msgid "missing argument for option \"%.50s\"\n"
-msgid "valid values for option '%s':\n"
-msgstr "\"%.50s\" seçeneği için değiştirge eksik\n"
-
-#, fuzzy, c-format
#| msgid "unknown option `%s'\n"
msgid "unknown TOFU policy '%s'\n"
msgstr "`%s' seçeneği bilinmiyor\n"
@@ -2263,11 +2273,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr ""
#, fuzzy, c-format
-#| msgid "missing argument for option \"%.50s\"\n"
-msgid "invalid value for option '%s'\n"
-msgstr "\"%.50s\" seçeneği için değiştirge eksik\n"
-
-#, fuzzy, 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"
@@ -2413,9 +2418,6 @@ msgstr "%s olmasından dolayı güvensiz bellekle çalıştırılmayacak\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "seçilen şifre algoritması geçersiz\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "seçilen özet algoritması geçersiz\n"
-
msgid "selected compression algorithm is invalid\n"
msgstr "seçilen şifre algoritması geçersiz\n"
@@ -2462,18 +2464,13 @@ msgid "%s does not yet work with %s\n"
msgstr "%s, %s ile henüz çalışmıyor\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 "%2$s kipindeyken '%1$s' şifreleme algoritması kullanılamaz\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"
+msgid "digest algorithm '%s' may not be used in %s mode\n"
msgstr "%2$s kipindeyken '%1$s' özet algoritması kullanılamaz\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"
+msgid "compression algorithm '%s' may not be used in %s mode\n"
msgstr "%2$s kipindeyken '%1$s' sıkıştırma algoritması kullanılamaz\n"
#, c-format
@@ -2492,15 +2489,17 @@ msgstr "`%s' için simetrik şifreleme başarısız: %s\n"
msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr "--s2k-mode 0 ile --symmetric --encrypt kullanamazsınız\n"
-#, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "%s kipindeyken --symmetric --encrypt kullanamazsınız\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr "--s2k-mode 0 ile --symmetric --sign --encrypt kullanamazsınız\n"
-#, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "%s kipindeyken --symmetric --sign --encrypt kullanamazsınız.\n"
#, c-format
@@ -2632,6 +2631,11 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr "girdinin ikilik biçimde olduğu kabul edilir"
+#, fuzzy
+#| msgid "show key fingerprint"
+msgid "repair keys on import"
+msgstr "parmakizini gösterir"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "%d türündeki blok atlanıyor\n"
@@ -3038,66 +3042,6 @@ msgstr "[yürürlükten kaldırma]"
msgid "[self-signature]"
msgstr "[öz-imza]"
-#, fuzzy, c-format
-#| msgid "error allocating enough memory: %s\n"
-msgid "error allocating memory: %s\n"
-msgstr "yeterli bellek ayrılırken hata: %s\n"
-
-#, fuzzy, c-format
-#| msgid "key %s: unsupported public key algorithm\n"
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "anahtar %s: genel anahtar algoritması desteklenmiyor\n"
-
-#, fuzzy, c-format
-#| msgid "card does not support digest algorithm %s\n"
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "kart %s özet algoritmasını desteklemiyor\n"
-
-#, fuzzy
-#| msgid "Good signature from"
-msgid " (reordered signatures follow)"
-msgstr "Buradaki imzeler iyi:"
-
-#, fuzzy, c-format
-#| msgid "skipped \"%s\": %s\n"
-msgid "key %s:\n"
-msgstr "\"%s\" atlandı: %s\n"
-
-#, fuzzy, c-format
-#| msgid "User ID \"%s\": %d signature removed\n"
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "Kullanıcı kimliği \"%s\": %d imza temizlendi\n"
-msgstr[1] "Kullanıcı kimliği \"%s\": %d imza temizlendi\n"
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "1 imza kayıp bir anahtar yüzünden kontrol edilmedi\n"
-msgstr[1] "1 imza kayıp bir anahtar yüzünden kontrol edilmedi\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d kötü imza\n"
-msgstr[1] "%d kötü imza\n"
-
-#, fuzzy, c-format
-#| msgid "Good signature from"
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "Buradaki imzeler iyi:"
-msgstr[1] "Buradaki imzeler iyi:"
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
"keys\n"
@@ -3617,6 +3561,16 @@ msgstr "%s anahtarı ile imzalanacak hiçbir şey yok\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "'%s' geçerli bir imza zamanaşımı değil\n"
+#, fuzzy, c-format
+#| msgid "invalid fingerprint"
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "parmakizi geçersiz"
+
+#, fuzzy, c-format
+#| msgid "key \"%s\" not found: %s\n"
+msgid "subkey \"%s\" not found\n"
+msgstr "anahtar \"%s\" yok: %s\n"
+
msgid "Digest: "
msgstr "Özet: "
@@ -3963,6 +3917,11 @@ msgstr ""
"gösteriliyor\n"
#, fuzzy, c-format
+#| msgid "missing argument for option \"%.50s\"\n"
+msgid "invalid value for option '%s'\n"
+msgstr "\"%.50s\" seçeneği için değiştirge eksik\n"
+
+#, fuzzy, c-format
#| msgid "preference `%s' duplicated\n"
msgid "preference '%s' duplicated\n"
msgstr "'%s' tercihi yinelendi\n"
@@ -4459,6 +4418,20 @@ msgstr[0] "%d kötü imza\n"
msgstr[1] "%d kötü imza\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d kötü imza\n"
+msgstr[1] "%d kötü imza\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "1 imza kayıp bir anahtar yüzünden kontrol edilmedi\n"
+msgstr[1] "1 imza kayıp bir anahtar yüzünden kontrol edilmedi\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4740,6 +4713,11 @@ msgstr "[şüpheli]"
msgid " aka \"%s\""
msgstr " nam-ı diğer \"%s\""
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr "UYARI: Bu anahtar güven dereceli bir imza ile sertifikalanmamış!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "Bu imzanın geçerliliği %s de bitti.\n"
@@ -5312,6 +5290,11 @@ msgstr "imzalı veri '%s' açılamadı\n"
msgid "can't open signed data fd=%d: %s\n"
msgstr "imzalı veri fd=%d açılamadı: %s\n"
+#, fuzzy, c-format
+#| msgid "certificate is not usable for encryption\n"
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "sertifika şifreleme için elverişli değil\n"
+
#, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "anonim alıcı: %s gizli anahtarı deneniyor ...\n"
@@ -5495,6 +5478,11 @@ msgstr "DSA anahtarı %s, %u bitlik veya daha geniş bir çittirim gerektiriyor\
msgid "WARNING: signature digest conflict in message\n"
msgstr "UYARI: iletideki imza özeti çelişkili\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "%2$s kipindeyken %1$s kullanılamayabilir.\n"
+
#, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr "UYARI: yardımcı imzalama anahtarı %s çapraz sertifikalı değil\n"
@@ -8456,6 +8444,16 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr ""
#, fuzzy, c-format
+#| msgid "error running `%s': exit status %d\n"
+msgid "error accessing '%s': http status %u\n"
+msgstr "`%s' çalışırken hata: çıkış durumu: %d\n"
+
+#, fuzzy, c-format
+#| msgid "error allocating enough memory: %s\n"
+msgid "error allocating memory: %s\n"
+msgstr "yeterli bellek ayrılırken hata: %s\n"
+
+#, fuzzy, c-format
#| msgid "error writing to %s: %s\n"
msgid "error printing log line: %s\n"
msgstr "%s yazılırken hata: %s\n"
@@ -8578,11 +8576,6 @@ msgid "error reading HTTP response for '%s': %s\n"
msgstr "%s okunurken hata: %s\n"
#, fuzzy, c-format
-#| msgid "error running `%s': exit status %d\n"
-msgid "error accessing '%s': http status %u\n"
-msgstr "`%s' çalışırken hata: çıkış durumu: %d\n"
-
-#, fuzzy, c-format
#| msgid "error binding socket to `%s': %s\n"
msgid "error parsing OCSP response for '%s': %s\n"
msgstr "soket `%s'e bağlanırken hata: %s\n"
@@ -9258,6 +9251,51 @@ msgstr ""
"Standart girdiden verilen anahtar parolasını örüntü dosyasıyla "
"karşılaştırır\n"
+#~ msgid "Error: URL too long (limit is %d characters).\n"
+#~ msgstr "Hata: URL çok uzun (sınır: %d karakter).\n"
+
+#~ msgid "Error: Login data too long (limit is %d characters).\n"
+#~ msgstr "Hata: Oturum açma verisi çok uzun (sınır: %d karakter).\n"
+
+#~ msgid "Error: Private DO too long (limit is %d characters).\n"
+#~ msgstr "Hata: Özel DO çok uzun (sınır: %d karakter).\n"
+
+#, fuzzy
+#~| msgid "key %s: unsupported public key algorithm\n"
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "anahtar %s: genel anahtar algoritması desteklenmiyor\n"
+
+#, fuzzy
+#~| msgid "card does not support digest algorithm %s\n"
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "kart %s özet algoritmasını desteklemiyor\n"
+
+#, fuzzy
+#~| msgid "Good signature from"
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "Buradaki imzeler iyi:"
+
+#, fuzzy
+#~| msgid "skipped \"%s\": %s\n"
+#~ msgid "key %s:\n"
+#~ msgstr "\"%s\" atlandı: %s\n"
+
+#, fuzzy
+#~| msgid "User ID \"%s\": %d signature removed\n"
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "Kullanıcı kimliği \"%s\": %d imza temizlendi\n"
+#~ msgstr[1] "Kullanıcı kimliği \"%s\": %d imza temizlendi\n"
+
+#, fuzzy
+#~| msgid "Good signature from"
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "Buradaki imzeler iyi:"
+#~ msgstr[1] "Buradaki imzeler iyi:"
+
#, fuzzy
#~| msgid "new configuration file `%s' created\n"
#~ msgid "new configuration file '%s' created\n"
diff --git a/po/uk.po b/po/uk.po
index 5102058..818b731 100644
--- a/po/uk.po
+++ b/po/uk.po
@@ -375,6 +375,9 @@ msgstr "дозволити запит пароля з Emacs"
msgid "enable ssh support"
msgstr "увімкнути підтримку ssh"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
msgid "enable putty support"
msgstr "увімкнути підтримку putty"
@@ -398,6 +401,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr "вказано некоректне значення рівня діагностики «%s»\n"
+msgid "selected digest algorithm is invalid\n"
+msgstr "вибраний алгоритм побудови контрольних сум є некоректним\n"
+
#, c-format
msgid "Note: no default option file '%s'\n"
msgstr "ЗАУВАЖЕННЯ: не виявлено файла типових параметрів «%s»\n"
@@ -1208,6 +1214,11 @@ msgstr "сервер «%s» має версію, старішу за нашу (%
msgid "WARNING: %s\n"
msgstr "УВАГА: %s\n"
+#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s ще не може працювати разом з %s\n"
+
#, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "Не вдалося отримати доступ до картки OpenPGP: %s\n"
@@ -1270,10 +1281,6 @@ msgid "URL to retrieve public key: "
msgstr "Адреса для отримання відкритого ключа: "
#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr "Помилка: адреса є занадто довгою (максимум — %d символів).\n"
-
-#, c-format
msgid "error reading '%s': %s\n"
msgstr "помилка під час спроби читання «%s»: %s\n"
@@ -1284,19 +1291,9 @@ msgstr "помилка під час спроби читання «%s»: %s\n"
msgid "Login data (account name): "
msgstr "Дані користувача (назва запису): "
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr ""
-"Помилка: дані користувача є занадто довгими (максимум — %d символів).\n"
-
msgid "Private DO data: "
msgstr "Особисті дані DO: "
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr ""
-"Помилка: особисті дані D0 є занадто довгими (максимум — %d символів).\n"
-
msgid "Language preferences: "
msgstr "Основна мова: "
@@ -1579,6 +1576,16 @@ msgstr ""
"УВАГА: примусове використання симетричного шифру %s (%d) не відповідає "
"параметрам отримувача\n"
+#, fuzzy, c-format
+#| msgid "you may not use cipher algorithm '%s' while in %s mode\n"
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "не можна використовувати алгоритм шифрування «%s» у режимі %s\n"
+
+#, fuzzy, c-format
+#| msgid "WARNING: \"%s%s\" is an obsolete option - it has no effect\n"
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "УВАГА: «%s%s» є застарілим параметром — він не працюватиме\n"
+
#, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
@@ -1597,8 +1604,9 @@ msgstr ""
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s зашифровано для «%s»\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "не можна використовувати %s у режимі %s\n"
#, c-format
@@ -1764,6 +1772,10 @@ msgstr ""
msgid "using subkey %s instead of primary key %s\n"
msgstr "використовуємо підключ %s замість основного ключа %s\n"
+#, c-format
+msgid "valid values for option '%s':\n"
+msgstr "коректні значення параметра «%s»:\n"
+
msgid "make a signature"
msgstr "створити підпис"
@@ -2090,10 +2102,6 @@ msgid "show expiration dates during signature listings"
msgstr "показувати дати завершення строків дії у списку підписів"
#, c-format
-msgid "valid values for option '%s':\n"
-msgstr "коректні значення параметра «%s»:\n"
-
-#, c-format
msgid "unknown TOFU policy '%s'\n"
msgstr "невідомі правила TOFU «%s»\n"
@@ -2101,10 +2109,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr "(команда «help» виводить список можливих варіантів)\n"
#, c-format
-msgid "invalid value for option '%s'\n"
-msgstr "некоректне значення параметра «%s»\n"
-
-#, c-format
msgid "Note: old default options file '%s' ignored\n"
msgstr "ЗАУВАЖЕННЯ: застарілий файл типових параметрів «%s» проігноровано\n"
@@ -2244,9 +2248,6 @@ msgstr "не буде запущено з помилками у захисті
msgid "selected cipher algorithm is invalid\n"
msgstr "вибраний алгоритм шифрування є некоректним\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "вибраний алгоритм побудови контрольних сум є некоректним\n"
-
msgid "selected compression algorithm is invalid\n"
msgstr "вибраний алгоритм стискання є некоректним\n"
@@ -2293,18 +2294,16 @@ msgstr "некоректні особисті параметри стискан
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"
-
-#, c-format
-msgid "you may not use digest algorithm '%s' while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use digest algorithm '%s' while in %s mode\n"
+msgid "digest algorithm '%s' may not be used in %s mode\n"
msgstr ""
"не можна використовувати алгоритм створення контрольних сум «%s» у режимі "
"%s\n"
-#, c-format
-msgid "you may not use compression algorithm '%s' while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use compression algorithm '%s' while in %s mode\n"
+msgid "compression algorithm '%s' may not be used in %s mode\n"
msgstr "не можна використовувати алгоритм стискання «%s» у режимі %s\n"
#, c-format
@@ -2325,8 +2324,9 @@ msgstr ""
"не можна використовувати комбінацію --symmetric --encrypt у режимі --s2k-"
"mode 0\n"
-#, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr ""
"не можна використовувати комбінацію --symmetric --encrypt у режимі %s\n"
@@ -2335,8 +2335,9 @@ msgstr ""
"не можна використовувати комбінацію --symmetric --sign --encrypt у режимі --"
"s2k-mode 0\n"
-#, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr ""
"не можна використовувати комбінацію --symmetric --sign --encrypt у режимі "
"%s\n"
@@ -2459,6 +2460,11 @@ msgstr "запустити фільтри імпортування та експ
msgid "assume the GnuPG key backup format"
msgstr "припускати формат резервних копій ключів GnuPG"
+#, fuzzy
+#| msgid "show key during import"
+msgid "repair keys on import"
+msgstr "показувати ключ під час імпортування"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "пропускаємо блок типу %d\n"
@@ -2847,66 +2853,6 @@ msgstr "[відкликання]"
msgid "[self-signature]"
msgstr "[самопідпис]"
-#, c-format
-msgid "error allocating memory: %s\n"
-msgstr "помилка під час спроби отримання області пам’яті: %s\n"
-
-#, c-format
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr ""
-"неможливо перевірити підпис із непідтримуваним алгоритмом створення "
-"відкритого ключа (%d): %s.\n"
-
-#, c-format
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr ""
-"неможливо перевірити підпис із непідтримуваним алгоритмом створення "
-"контрольної суми %d: %s.\n"
-
-msgid " (reordered signatures follow)"
-msgstr " (нижче наведено перевпорядковані підписи)"
-
-#, c-format
-msgid "key %s:\n"
-msgstr "ключ %s:\n"
-
-#, c-format
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "вилучено %d дублікат підпису\n"
-msgstr[1] "вилучено %d дублікати підписів\n"
-msgstr[2] "вилучено %d дублікатів підписів\n"
-
-#, c-format
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "%d підпис не перевірено через те, що немає ключа\n"
-msgstr[1] "%d підписи не перевірено через те, що немає ключа\n"
-msgstr[2] "%d підписів не перевірено через те, що немає ключа\n"
-
-#, c-format
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d помилкових підпис\n"
-msgstr[1] "%d помилкових підписи\n"
-msgstr[2] "%d помилкових підписів\n"
-
-#, c-format
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "перевпорядковано %d підпис\n"
-msgstr[1] "перевпорядковано %d підписи\n"
-msgstr[2] "перевпорядковано %d підписів\n"
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-"Попередження: виявлено помилки, перевірка виконувалася лише для "
-"самопідписування, віддайте команду «%s», щоб перевірити усі підписи.\n"
-
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
"keys\n"
@@ -3388,6 +3334,16 @@ msgstr "Нічого підписувати.\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "«%s» не є коректним записом завершення строку дії\n"
+#, fuzzy, c-format
+#| msgid "\"%s\" is not a fingerprint\n"
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "«%s» не є відбитком\n"
+
+#, fuzzy, c-format
+#| msgid "key \"%s\" not found\n"
+msgid "subkey \"%s\" not found\n"
+msgstr "ключ «%s» не знайдено\n"
+
msgid "Digest: "
msgstr "Контрольна сума: "
@@ -3716,6 +3672,10 @@ msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
msgstr "Показ фотоідентифікатора %s розміру %ld для ключа %s (uid %d)\n"
#, c-format
+msgid "invalid value for option '%s'\n"
+msgstr "некоректне значення параметра «%s»\n"
+
+#, c-format
msgid "preference '%s' duplicated\n"
msgstr "запис переваги «%s» продубльовано\n"
@@ -4191,6 +4151,20 @@ msgstr[1] "%d добрих підписи\n"
msgstr[2] "%d добрих підписів\n"
#, c-format
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d помилкових підпис\n"
+msgstr[1] "%d помилкових підписи\n"
+msgstr[2] "%d помилкових підписів\n"
+
+#, c-format
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "%d підпис не перевірено через те, що немає ключа\n"
+msgstr[1] "%d підписи не перевірено через те, що немає ключа\n"
+msgstr[2] "%d підписів не перевірено через те, що немає ключа\n"
+
+#, c-format
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
msgstr[0] "%d підпис не перевірено через помилку\n"
@@ -4471,6 +4445,11 @@ msgstr "[непевний]"
msgid " aka \"%s\""
msgstr " або «%s»"
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr "УВАГА: цей ключ не сертифіковано за допомогою надійного підпису!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "Строк дії підпису вичерпано %s\n"
@@ -5013,6 +4992,11 @@ msgstr "не вдалося відкрити підписані дані «%s»\
msgid "can't open signed data fd=%d: %s\n"
msgstr "не вдалося відкрити підписані дані fd=%d: %s\n"
+#, fuzzy, c-format
+#| msgid "certificate is not usable for encryption\n"
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "сертифікат непридатний для шифрування\n"
+
#, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "анонімний отримувач; спробуємо закритий ключ %s ...\n"
@@ -5196,6 +5180,11 @@ msgstr ""
msgid "WARNING: signature digest conflict in message\n"
msgstr "УВАГА: конфлікт контрольних сум підписів у повідомленні\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "не можна використовувати %s у режимі %s\n"
+
#, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr "УВАГА: підписування підключа %s не є перехресно сертифікованим\n"
@@ -7984,6 +7973,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr "«%s» є некоректною адресою LDAP\n"
#, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "помилка під час спроби доступу до «%s»: стан http %u\n"
+
+#, c-format
+msgid "error allocating memory: %s\n"
+msgstr "помилка під час спроби отримання області пам’яті: %s\n"
+
+#, c-format
msgid "error printing log line: %s\n"
msgstr "помилка під час спроби виводу рядка журналу: %s\n"
@@ -8088,10 +8085,6 @@ 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"
@@ -8684,6 +8677,54 @@ msgstr ""
"Синтаксис: gpg-check-pattern [параметри] файл_шаблонів\n"
"Перевірити пароль, вказаний у stdin, за допомогою файла_шаблонів\n"
+#~ msgid "Error: URL too long (limit is %d characters).\n"
+#~ msgstr "Помилка: адреса є занадто довгою (максимум — %d символів).\n"
+
+#~ msgid "Error: Login data too long (limit is %d characters).\n"
+#~ msgstr ""
+#~ "Помилка: дані користувача є занадто довгими (максимум — %d символів).\n"
+
+#~ msgid "Error: Private DO too long (limit is %d characters).\n"
+#~ msgstr ""
+#~ "Помилка: особисті дані D0 є занадто довгими (максимум — %d символів).\n"
+
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr ""
+#~ "неможливо перевірити підпис із непідтримуваним алгоритмом створення "
+#~ "відкритого ключа (%d): %s.\n"
+
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr ""
+#~ "неможливо перевірити підпис із непідтримуваним алгоритмом створення "
+#~ "контрольної суми %d: %s.\n"
+
+#~ msgid " (reordered signatures follow)"
+#~ msgstr " (нижче наведено перевпорядковані підписи)"
+
+#~ msgid "key %s:\n"
+#~ msgstr "ключ %s:\n"
+
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "вилучено %d дублікат підпису\n"
+#~ msgstr[1] "вилучено %d дублікати підписів\n"
+#~ msgstr[2] "вилучено %d дублікатів підписів\n"
+
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "перевпорядковано %d підпис\n"
+#~ msgstr[1] "перевпорядковано %d підписи\n"
+#~ msgstr[2] "перевпорядковано %d підписів\n"
+
+#~ msgid ""
+#~ "Warning: errors found and only checked self-signatures, run '%s' to check "
+#~ "all signatures.\n"
+#~ msgstr ""
+#~ "Попередження: виявлено помилки, перевірка виконувалася лише для "
+#~ "самопідписування, віддайте команду «%s», щоб перевірити усі підписи.\n"
+
#~ msgid ", "
#~ msgstr ", "
diff --git a/po/zh_CN.po b/po/zh_CN.po
index f9b5548..acee43b 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -403,6 +403,9 @@ msgstr ""
msgid "enable ssh support"
msgstr "未被支持"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
#, fuzzy
#| msgid "not supported"
msgid "enable putty support"
@@ -429,6 +432,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr ""
+msgid "selected digest algorithm is invalid\n"
+msgstr "所选的散列算法无效\n"
+
#, fuzzy, c-format
#| msgid "NOTE: no default option file `%s'\n"
msgid "Note: no default option file '%s'\n"
@@ -1280,6 +1286,11 @@ msgstr ""
msgid "WARNING: %s\n"
msgstr "警告:"
+#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s 尚不能和 %s 并用\n"
+
#, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "OpenPGP 卡不可用:%s\n"
@@ -1342,10 +1353,6 @@ msgstr "错误:合成的姓名太长(至多 %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"
-
#, fuzzy, c-format
#| msgid "error reading `%s': %s\n"
msgid "error reading '%s': %s\n"
@@ -1358,17 +1365,9 @@ msgstr "写入钥匙环‘%s’时出错: %s\n"
msgid "Login data (account name): "
msgstr "登录数据(帐号名):"
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr "错误:登录数据太长(至多 %d 个字符)。\n"
-
msgid "Private DO data: "
msgstr "个人 DO 数据:"
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr "错误:个人 DO 太长(至多 %d 个字符)。\n"
-
msgid "Language preferences: "
msgstr "首选语言:"
@@ -1659,6 +1658,15 @@ msgid ""
"WARNING: forcing symmetric cipher %s (%d) violates recipient preferences\n"
msgstr "警告:强行使用的 %s (%d)对称加密算法不在收件者的首选项中\n"
+#, fuzzy, c-format
+#| msgid "you may not use cipher algorithm `%s' while in %s mode\n"
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "您不能在 %s 模式下使用‘%s’对称加密算法\n"
+
+#, fuzzy, c-format
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "警告:“%s”选项已不建议使用\n"
+
#, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
@@ -1673,8 +1681,9 @@ msgstr "强行使用的 %s (%d)对称加密算法不在收件者的首选项中\
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s 已经加密给:“%s”\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "您不该将 %s 用于 %s 模式中\n"
#, c-format
@@ -1842,6 +1851,10 @@ msgstr "--allow-non-selfsigned-uid 使无效密钥 %s 生效\n"
msgid "using subkey %s instead of primary key %s\n"
msgstr "使用子钥 %s 而非主钥 %s\n"
+#, fuzzy, c-format
+msgid "valid values for option '%s':\n"
+msgstr "无效的列表选项\n"
+
#, fuzzy
msgid "make a signature"
msgstr "|[文件名]|生成一份签名"
@@ -2204,10 +2217,6 @@ msgid "show expiration dates during signature listings"
msgstr "列出签名时显示过期日期"
#, fuzzy, c-format
-msgid "valid values for option '%s':\n"
-msgstr "无效的列表选项\n"
-
-#, fuzzy, c-format
#| msgid "unknown option `%s'\n"
msgid "unknown TOFU policy '%s'\n"
msgstr "未知的选项 '%s'\n"
@@ -2216,10 +2225,6 @@ msgid "(use \"help\" to list choices)\n"
msgstr ""
#, fuzzy, c-format
-msgid "invalid value for option '%s'\n"
-msgstr "无效的列表选项\n"
-
-#, fuzzy, c-format
#| msgid "NOTE: old default options file `%s' ignored\n"
msgid "Note: old default options file '%s' ignored\n"
msgstr "注意:旧式的默认配置文件‘%s’已被忽略\n"
@@ -2360,9 +2365,6 @@ msgstr "不会在内存不安全的情况下运行,原因是 %s\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "所选的对称加密算法无效\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "所选的散列算法无效\n"
-
msgid "selected compression algorithm is invalid\n"
msgstr "所选的压缩算法无效\n"
@@ -2409,18 +2411,13 @@ 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"
+msgid "digest algorithm '%s' may not be used 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"
+msgid "compression algorithm '%s' may not be used in %s mode\n"
msgstr "您不能在 %s 模式下使用‘%s’压缩算法\n"
#, c-format
@@ -2438,15 +2435,17 @@ msgstr "对称加密‘%s’失败:%s\n"
msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr "使用 --symmetric --encrypt 时不能使用 --s2k-mode 0\n"
-#, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "您不能在 %s 模式下使用 --symmetric -encrypt\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr "使用 --symmetric --sign --encrypt 时不能使用 --s2k-mode 0\n"
-#, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "您不能在 %s 模式下使用 --symmetric --sign -encrypt\n"
#, c-format
@@ -2576,6 +2575,11 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr ""
+#, fuzzy
+#| msgid "show key fingerprint"
+msgid "repair keys on import"
+msgstr "显示密钥指纹"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "跳过 %d 样式的区块\n"
@@ -2965,62 +2969,6 @@ msgstr "[吊销]"
msgid "[self-signature]"
msgstr "[自身签名]"
-#, fuzzy, c-format
-msgid "error allocating memory: %s\n"
-msgstr "建立钥匙环‘%s’时发生错误:%s\n"
-
-#, fuzzy, c-format
-#| msgid "key %s: unsupported public key algorithm\n"
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "密钥 %s:不支持的公钥算法\n"
-
-#, fuzzy, c-format
-#| msgid "card does not support digest algorithm %s\n"
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "卡不支持散列算法 %s\n"
-
-#, fuzzy
-msgid " (reordered signatures follow)"
-msgstr "完好的签名,来自于“%s”"
-
-#, fuzzy, c-format
-#| msgid "skipped \"%s\": %s\n"
-msgid "key %s:\n"
-msgstr "“%s”已跳过:%s\n"
-
-#, fuzzy, c-format
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "密钥 %s:“%s”%d 个签名被清除\n"
-msgstr[1] "密钥 %s:“%s”%d 个签名被清除\n"
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "有 1 份签名因为遗失密钥而未被检查\n"
-msgstr[1] "有 1 份签名因为遗失密钥而未被检查\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d 个损坏的签名\n"
-msgstr[1] "%d 个损坏的签名\n"
-
-#, fuzzy, c-format
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "完好的签名,来自于“%s”"
-msgstr[1] "完好的签名,来自于“%s”"
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
"keys\n"
@@ -3499,6 +3447,16 @@ msgstr "没有东西可以让密钥 %s 签名\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "‘%s’不是一个有效的签名过期日期\n"
+#, fuzzy, c-format
+#| msgid "invalid fingerprint"
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "指纹无效"
+
+#, fuzzy, c-format
+#| msgid "key \"%s\" not found: %s\n"
+msgid "subkey \"%s\" not found\n"
+msgstr "密钥‘%s’找不到:%s\n"
+
msgid "Digest: "
msgstr "散列:"
@@ -3821,6 +3779,10 @@ msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
msgstr "正在显示 %s 照片标识(大小为 %ld,属于密钥 %s,用户标识 %d)\n"
#, fuzzy, c-format
+msgid "invalid value for option '%s'\n"
+msgstr "无效的列表选项\n"
+
+#, fuzzy, c-format
#| msgid "preference `%s' duplicated\n"
msgid "preference '%s' duplicated\n"
msgstr "首选项‘%s’重复\n"
@@ -4300,6 +4262,20 @@ msgstr[0] "%d 个损坏的签名\n"
msgstr[1] "%d 个损坏的签名\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d 个损坏的签名\n"
+msgstr[1] "%d 个损坏的签名\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "有 1 份签名因为遗失密钥而未被检查\n"
+msgstr[1] "有 1 份签名因为遗失密钥而未被检查\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4577,6 +4553,11 @@ msgstr "[不确定]"
msgid " aka \"%s\""
msgstr " 亦即“%s”"
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr "警告:这把密钥未经受信任的签名认证!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "这份签名已于 %s 过期。\n"
@@ -5126,6 +5107,10 @@ msgstr "无法打开有签名的数据‘%s’\n"
msgid "can't open signed data fd=%d: %s\n"
msgstr "无法打开有签名的数据‘%s’\n"
+#, fuzzy, c-format
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "密钥 %s:没有有效的用户标识\n"
+
#, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "匿名收件者;正在尝试使用私钥 %s ……\n"
@@ -5299,6 +5284,11 @@ msgstr "DSA 密钥 %s 需要 %u 位或更长的散列\n"
msgid "WARNING: signature digest conflict in message\n"
msgstr "警告:签名散列值与报文不一致\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "您不该将 %s 用于 %s 模式中\n"
+
#, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr "警告:签名的子钥 %s 未经交叉验证\n"
@@ -8086,6 +8076,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr ""
#, fuzzy, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "读取‘%s’时出错:%s\n"
+
+#, fuzzy, c-format
+msgid "error allocating memory: %s\n"
+msgstr "建立钥匙环‘%s’时发生错误:%s\n"
+
+#, fuzzy, c-format
msgid "error printing log line: %s\n"
msgstr "写入钥匙环‘%s’时出错: %s\n"
@@ -8196,10 +8194,6 @@ msgid "error reading HTTP response for '%s': %s\n"
msgstr "读取‘%s’时出错:%s\n"
#, fuzzy, c-format
-msgid "error accessing '%s': http status %u\n"
-msgstr "读取‘%s’时出错:%s\n"
-
-#, fuzzy, c-format
msgid "error parsing OCSP response for '%s': %s\n"
msgstr "在‘%s’中寻找信任度记录时出错:%s\n"
@@ -8818,6 +8812,48 @@ msgid ""
"Check a passphrase given on stdin against the patternfile\n"
msgstr ""
+#~ msgid "Error: URL too long (limit is %d characters).\n"
+#~ msgstr "错误:URL 太长(至多 %d 个字符)\n"
+
+#~ msgid "Error: Login data too long (limit is %d characters).\n"
+#~ msgstr "错误:登录数据太长(至多 %d 个字符)。\n"
+
+#~ msgid "Error: Private DO too long (limit is %d characters).\n"
+#~ msgstr "错误:个人 DO 太长(至多 %d 个字符)。\n"
+
+#, fuzzy
+#~| msgid "key %s: unsupported public key algorithm\n"
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "密钥 %s:不支持的公钥算法\n"
+
+#, fuzzy
+#~| msgid "card does not support digest algorithm %s\n"
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "卡不支持散列算法 %s\n"
+
+#, fuzzy
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "完好的签名,来自于“%s”"
+
+#, fuzzy
+#~| msgid "skipped \"%s\": %s\n"
+#~ msgid "key %s:\n"
+#~ msgstr "“%s”已跳过:%s\n"
+
+#, fuzzy
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "密钥 %s:“%s”%d 个签名被清除\n"
+#~ msgstr[1] "密钥 %s:“%s”%d 个签名被清除\n"
+
+#, fuzzy
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "完好的签名,来自于“%s”"
+#~ msgstr[1] "完好的签名,来自于“%s”"
+
#, fuzzy
#~| msgid "new configuration file `%s' created\n"
#~ msgid "new configuration file '%s' created\n"
diff --git a/po/zh_TW.po b/po/zh_TW.po
index 637ec29..83f9ca9 100644
--- a/po/zh_TW.po
+++ b/po/zh_TW.po
@@ -381,6 +381,9 @@ msgstr ""
msgid "enable ssh support"
msgstr "啟用 ssh 支援"
+msgid "|ALGO|use ALGO to show ssh fingerprints"
+msgstr ""
+
msgid "enable putty support"
msgstr "啟用 putty 支援"
@@ -404,6 +407,9 @@ msgstr ""
msgid "invalid debug-level '%s' given\n"
msgstr "給定的除錯等級 '%s' 無效\n"
+msgid "selected digest algorithm is invalid\n"
+msgstr "所選的摘要演算法無效\n"
+
#, c-format
msgid "Note: no default option file '%s'\n"
msgstr "請注意: 沒有預設選項檔 '%s'\n"
@@ -1209,6 +1215,11 @@ msgstr ""
msgid "WARNING: %s\n"
msgstr "警告: %s 會推翻 %s\n"
+#, fuzzy, c-format
+#| msgid "%s does not yet work with %s\n"
+msgid "%s is not compliant with %s mode\n"
+msgstr "%s 還沒辦法跟 %s 一起運作\n"
+
#, c-format
msgid "OpenPGP card not available: %s\n"
msgstr "沒有可用的 OpenPGP 卡片: %s\n"
@@ -1270,10 +1281,6 @@ msgid "URL to retrieve public key: "
msgstr "取回公鑰的 URL: "
#, c-format
-msgid "Error: URL too long (limit is %d characters).\n"
-msgstr "錯誤: URL 太長 (上限是 %d 個字符).\n"
-
-#, c-format
msgid "error reading '%s': %s\n"
msgstr "讀取 '%s' 時出錯: %s\n"
@@ -1284,17 +1291,9 @@ msgstr "寫入 '%s' 時出錯: %s\n"
msgid "Login data (account name): "
msgstr "登入資料 (帳號名稱): "
-#, c-format
-msgid "Error: Login data too long (limit is %d characters).\n"
-msgstr "錯誤: 登入資料太長 (上限是 %d 個字符).\n"
-
msgid "Private DO data: "
msgstr "私人的 DO 資料: "
-#, c-format
-msgid "Error: Private DO too long (limit is %d characters).\n"
-msgstr "錯誤: 私人的 DO 太長 (上限是 %d 個字符).\n"
-
msgid "Language preferences: "
msgstr "介面語言偏好設定: "
@@ -1576,6 +1575,16 @@ msgid ""
"WARNING: forcing symmetric cipher %s (%d) violates recipient preferences\n"
msgstr "警告: 強迫使用 %s (%d) 對稱式編密法會違反收件者偏好設定\n"
+#, fuzzy, c-format
+#| msgid "you may not use cipher algorithm '%s' while in %s mode\n"
+msgid "cipher algorithm '%s' may not be used in %s mode\n"
+msgstr "你不該將 '%s' 編密演算法用於 %s 模式\n"
+
+#, fuzzy, c-format
+#| msgid "WARNING: \"%s%s\" is an obsolete option - it has no effect\n"
+msgid "WARNING: key %s is not suitable for encryption in %s mode\n"
+msgstr "警告: \"%s%s\" 是已廢棄的選項 - 沒有效果\n"
+
#, c-format
msgid ""
"WARNING: forcing compression algorithm %s (%d) violates recipient "
@@ -1590,8 +1599,9 @@ msgstr "強迫使用 %s (%d) 對稱式編密法會違反收件者偏好設定\n"
msgid "%s/%s encrypted for: \"%s\"\n"
msgstr "%s/%s 已加密給: \"%s\"\n"
-#, c-format
-msgid "you may not use %s while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "option '%s' may not be used in %s mode\n"
msgstr "你不能夠將 %s 用於 %s 模式中\n"
#, c-format
@@ -1751,6 +1761,11 @@ msgstr "無效的金鑰 %s 可以藉由 --allow-non-selfsigned-uid 而生效\n"
msgid "using subkey %s instead of primary key %s\n"
msgstr "使用子鑰 %s 來替換主鑰 %s\n"
+#, fuzzy, c-format
+#| msgid "invalid argument for option \"%.50s\"\n"
+msgid "valid values for option '%s':\n"
+msgstr "選項 \"%.50s\" 的引數無效\n"
+
msgid "make a signature"
msgstr "建立簽章"
@@ -2073,11 +2088,6 @@ msgid "show expiration dates during signature listings"
msgstr "列出簽章時顯示有效期限"
#, fuzzy, c-format
-#| msgid "invalid argument for option \"%.50s\"\n"
-msgid "valid values for option '%s':\n"
-msgstr "選項 \"%.50s\" 的引數無效\n"
-
-#, fuzzy, c-format
#| msgid "unknown option '%s'\n"
msgid "unknown TOFU policy '%s'\n"
msgstr "未知的選項 '%s'\n"
@@ -2085,11 +2095,6 @@ msgstr "未知的選項 '%s'\n"
msgid "(use \"help\" to list choices)\n"
msgstr ""
-#, fuzzy, c-format
-#| msgid "invalid argument for option \"%.50s\"\n"
-msgid "invalid value for option '%s'\n"
-msgstr "選項 \"%.50s\" 的引數無效\n"
-
#, c-format
msgid "Note: old default options file '%s' ignored\n"
msgstr "請注意: 已忽略舊有的預設選項檔 '%s'\n"
@@ -2227,9 +2232,6 @@ msgstr "因為 %s 而不會在不安全的記憶體中執行\n"
msgid "selected cipher algorithm is invalid\n"
msgstr "所選的編密演算法無效\n"
-msgid "selected digest algorithm is invalid\n"
-msgstr "所選的摘要演算法無效\n"
-
msgid "selected compression algorithm is invalid\n"
msgstr "所選的壓縮演算法無效\n"
@@ -2273,16 +2275,14 @@ msgstr "無效的個人壓縮偏好\n"
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"
-
-#, c-format
-msgid "you may not use digest algorithm '%s' while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use digest algorithm '%s' while in %s mode\n"
+msgid "digest algorithm '%s' may not be used in %s mode\n"
msgstr "你不該將 '%s' 摘要演算法用於 %s 模式\n"
-#, c-format
-msgid "you may not use compression algorithm '%s' while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you may not use compression algorithm '%s' while in %s mode\n"
+msgid "compression algorithm '%s' may not be used in %s mode\n"
msgstr "你不該將 '%s' 壓縮演算法用於 %s 模式\n"
#, c-format
@@ -2299,15 +2299,17 @@ msgstr "'%s' 對稱式加密失敗: %s\n"
msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
msgstr "你不能在 --s2k-mode 0 中使用 --symmetric --encrypt\n"
-#, c-format
-msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --encrypt in %s mode\n"
msgstr "你不能在 %s 模式中使用 --symmetric --encrypt\n"
msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
msgstr "你不能在 --s2k-mode 0 中使用 --symmetric --sign --encrypt\n"
-#, c-format
-msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+#, fuzzy, c-format
+#| msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
+msgid "you cannot use --symmetric --sign --encrypt in %s mode\n"
msgstr "你不能在 %s 模式中使用 --symmetric --sign --encrypt\n"
#, c-format
@@ -2436,6 +2438,11 @@ msgstr ""
msgid "assume the GnuPG key backup format"
msgstr "假設輸入的是二進制格式"
+#, fuzzy
+#| msgid "show key fingerprint"
+msgid "repair keys on import"
+msgstr "顯示金鑰指紋"
+
#, c-format
msgid "skipping block of type %d\n"
msgstr "正在跳過 %d 型態的區塊\n"
@@ -2819,61 +2826,6 @@ msgstr "[撤銷]"
msgid "[self-signature]"
msgstr "[自我簽章]"
-#, c-format
-msgid "error allocating memory: %s\n"
-msgstr "配置記憶體時出錯: %s\n"
-
-#, fuzzy, c-format
-#| msgid "key %s: unsupported public key algorithm\n"
-msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n"
-msgstr "金鑰 %s: 未支援的公鑰演算法\n"
-
-#, fuzzy, c-format
-#| msgid "card does not support digest algorithm %s\n"
-msgid ""
-"can't check signature with unsupported message-digest algorithm %d: %s.\n"
-msgstr "卡片不支援 %s 摘要演算法\n"
-
-#, fuzzy
-#| msgid "Good signature from"
-msgid " (reordered signatures follow)"
-msgstr "完好的簽章來自於"
-
-#, fuzzy, c-format
-#| msgid "key %s: %s\n"
-msgid "key %s:\n"
-msgstr "金鑰 %s: %s\n"
-
-#, fuzzy, c-format
-#| msgid "User ID \"%s\": %d signature removed\n"
-msgid "%d duplicate signature removed\n"
-msgid_plural "%d duplicate signatures removed\n"
-msgstr[0] "使用者 ID \"%s\": 已移除 %d 份簽章\n"
-
-#, fuzzy, c-format
-#| msgid "1 signature not checked due to a missing key\n"
-msgid "%d signature not checked due to a missing key\n"
-msgid_plural "%d signatures not checked due to missing keys\n"
-msgstr[0] "有 1 份簽章因為遺失金鑰而未被檢查\n"
-
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
-msgid "%d bad signature\n"
-msgid_plural "%d bad signatures\n"
-msgstr[0] "%d 份損壞的簽章\n"
-
-#, fuzzy, c-format
-#| msgid "Good signature from"
-msgid "%d signature reordered\n"
-msgid_plural "%d signatures reordered\n"
-msgstr[0] "完好的簽章來自於"
-
-#, c-format
-msgid ""
-"Warning: errors found and only checked self-signatures, run '%s' to check "
-"all signatures.\n"
-msgstr ""
-
msgid ""
"Please decide how far you trust this user to correctly verify other users' "
"keys\n"
@@ -3340,6 +3292,16 @@ msgstr "沒有東西可以簽署.\n"
msgid "'%s' is not a valid expiration time\n"
msgstr "'%s' 不是有效的簽章使用期限\n"
+#, fuzzy, c-format
+#| msgid "\"%s\" is not a fingerprint\n"
+msgid "\"%s\" is not a proper fingerprint\n"
+msgstr "\"%s\" 不是指紋\n"
+
+#, fuzzy, c-format
+#| msgid "key \"%s\" not found: %s\n"
+msgid "subkey \"%s\" not found\n"
+msgstr "找不到金鑰 \"%s\": %s\n"
+
msgid "Digest: "
msgstr "摘要: "
@@ -3660,6 +3622,11 @@ msgstr "子鑰 %s 已撤銷.\n"
msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n"
msgstr "正在顯示 %s 照片 ID, 其尺寸為 %ld, 屬於金鑰 %s (uid %d) 的照片\n"
+#, fuzzy, c-format
+#| msgid "invalid argument for option \"%.50s\"\n"
+msgid "invalid value for option '%s'\n"
+msgstr "選項 \"%.50s\" 的引數無效\n"
+
#, c-format
msgid "preference '%s' duplicated\n"
msgstr "偏好設定 '%s' 重複了\n"
@@ -4119,6 +4086,18 @@ msgid_plural "%d good signatures\n"
msgstr[0] "%d 份損壞的簽章\n"
#, fuzzy, c-format
+#| msgid "%d bad signatures\n"
+msgid "%d bad signature\n"
+msgid_plural "%d bad signatures\n"
+msgstr[0] "%d 份損壞的簽章\n"
+
+#, fuzzy, c-format
+#| msgid "1 signature not checked due to a missing key\n"
+msgid "%d signature not checked due to a missing key\n"
+msgid_plural "%d signatures not checked due to missing keys\n"
+msgstr[0] "有 1 份簽章因為遺失金鑰而未被檢查\n"
+
+#, fuzzy, c-format
#| msgid "1 signature not checked due to an error\n"
msgid "%d signature not checked due to an error\n"
msgid_plural "%d signatures not checked due to errors\n"
@@ -4388,6 +4367,11 @@ msgstr "[ 不確定 ]"
msgid " aka \"%s\""
msgstr " 亦即 \"%s\""
+#, fuzzy, c-format
+#| msgid "WARNING: This key is not certified with a trusted signature!\n"
+msgid "WARNING: This key is not suitable for signing in %s mode\n"
+msgstr "警告: 這把金鑰並非以受信任的簽章所認證!\n"
+
#, c-format
msgid "Signature expired %s\n"
msgstr "這份簽署已經在 %s 過期了\n"
@@ -4922,6 +4906,11 @@ msgstr "無法開啟被簽署過的資料 '%s'\n"
msgid "can't open signed data fd=%d: %s\n"
msgstr "無法開啟被簽署過的資料 fd=%d: %s\n"
+#, fuzzy, c-format
+#| msgid "certificate is not usable for encryption\n"
+msgid "Note: key %s is not suitable for encryption in %s mode\n"
+msgstr "憑證無法用於加密\n"
+
#, c-format
msgid "anonymous recipient; trying secret key %s ...\n"
msgstr "匿名收件者; 正在嘗試使用私鑰 %s ...\n"
@@ -5108,6 +5097,11 @@ msgstr "%s 金鑰 %s 需要 %zu 位元以上的雜湊 (雜湊為 %s)\n"
msgid "WARNING: signature digest conflict in message\n"
msgstr "警告: 簽章摘要與訊息不一致\n"
+#, fuzzy, c-format
+#| msgid "you may not use %s while in %s mode\n"
+msgid "key %s may not be used for signing in %s mode\n"
+msgstr "你不能夠將 %s 用於 %s 模式中\n"
+
#, c-format
msgid "WARNING: signing subkey %s is not cross-certified\n"
msgstr "警告: 簽署子鑰 %s 未經交叉認證\n"
@@ -7749,6 +7743,14 @@ msgid "'%s' is an invalid LDAP URL\n"
msgstr "'%s' 是無效的 LDAP 網址\n"
#, c-format
+msgid "error accessing '%s': http status %u\n"
+msgstr "存取 '%s' 時出錯: http 狀態 %u\n"
+
+#, c-format
+msgid "error allocating memory: %s\n"
+msgstr "配置記憶體時出錯: %s\n"
+
+#, c-format
msgid "error printing log line: %s\n"
msgstr "印出日誌記錄列時出錯: %s\n"
@@ -7854,10 +7856,6 @@ 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"
@@ -8463,6 +8461,49 @@ msgstr ""
"語法: gpg-check-pattern [選項] 樣式檔案\n"
"用樣式檔案來檢查由標準輸入給定的密語\n"
+#~ msgid "Error: URL too long (limit is %d characters).\n"
+#~ msgstr "錯誤: URL 太長 (上限是 %d 個字符).\n"
+
+#~ msgid "Error: Login data too long (limit is %d characters).\n"
+#~ msgstr "錯誤: 登入資料太長 (上限是 %d 個字符).\n"
+
+#~ msgid "Error: Private DO too long (limit is %d characters).\n"
+#~ msgstr "錯誤: 私人的 DO 太長 (上限是 %d 個字符).\n"
+
+#, fuzzy
+#~| msgid "key %s: unsupported public key algorithm\n"
+#~ msgid ""
+#~ "can't check signature with unsupported public-key algorithm (%d): %s.\n"
+#~ msgstr "金鑰 %s: 未支援的公鑰演算法\n"
+
+#, fuzzy
+#~| msgid "card does not support digest algorithm %s\n"
+#~ msgid ""
+#~ "can't check signature with unsupported message-digest algorithm %d: %s.\n"
+#~ msgstr "卡片不支援 %s 摘要演算法\n"
+
+#, fuzzy
+#~| msgid "Good signature from"
+#~ msgid " (reordered signatures follow)"
+#~ msgstr "完好的簽章來自於"
+
+#, fuzzy
+#~| msgid "key %s: %s\n"
+#~ msgid "key %s:\n"
+#~ msgstr "金鑰 %s: %s\n"
+
+#, fuzzy
+#~| msgid "User ID \"%s\": %d signature removed\n"
+#~ msgid "%d duplicate signature removed\n"
+#~ msgid_plural "%d duplicate signatures removed\n"
+#~ msgstr[0] "使用者 ID \"%s\": 已移除 %d 份簽章\n"
+
+#, fuzzy
+#~| msgid "Good signature from"
+#~ msgid "%d signature reordered\n"
+#~ msgid_plural "%d signatures reordered\n"
+#~ msgstr[0] "完好的簽章來自於"
+
#~ msgid "new configuration file '%s' created\n"
#~ msgstr "新的組態檔案 '%s' 已建立\n"
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index 25f3dbe..365f246 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -76,21 +76,24 @@ static struct {
int tag;
int constructed;
int get_from; /* Constructed DO with this DO or 0 for direct access. */
- int binary:1;
- int dont_cache:1;
- int flush_on_error:1;
- int get_immediate_in_v11:1; /* Enable a hack to bypass the cache of
+ unsigned int binary:1;
+ unsigned int dont_cache:1;
+ unsigned int flush_on_error:1;
+ unsigned int get_immediate_in_v11:1; /* Enable a hack to bypass the cache of
this data object if it is used in 1.1
and later versions of the card. This
does not work with composite DO and
is currently only useful for the CHV
status bytes. */
- int try_extlen:1; /* Large object; try to use an extended
- length APDU. */
+ unsigned int try_extlen:2; /* Large object; try to use an extended
+ length APDU when !=0. The size is
+ determined by extcap.max_certlen_3
+ when == 1, and by extcap.max_special_do
+ when == 2. */
char *desc;
} data_objects[] = {
- { 0x005E, 0, 0, 1, 0, 0, 0, 0, "Login Data" },
- { 0x5F50, 0, 0, 0, 0, 0, 0, 0, "URL" },
+ { 0x005E, 0, 0, 1, 0, 0, 0, 2, "Login Data" },
+ { 0x5F50, 0, 0, 0, 0, 0, 0, 2, "URL" },
{ 0x5F52, 0, 0, 1, 0, 0, 0, 0, "Historical Bytes" },
{ 0x0065, 1, 0, 1, 0, 0, 0, 0, "Cardholder Related Data"},
{ 0x005B, 0, 0x65, 0, 0, 0, 0, 0, "Name" },
@@ -110,10 +113,10 @@ static struct {
{ 0x00CD, 0, 0x6E, 1, 0, 0, 0, 0, "Generation time" },
{ 0x007A, 1, 0, 1, 0, 0, 0, 0, "Security Support Template" },
{ 0x0093, 0, 0x7A, 1, 1, 0, 0, 0, "Digital Signature Counter" },
- { 0x0101, 0, 0, 0, 0, 0, 0, 0, "Private DO 1"},
- { 0x0102, 0, 0, 0, 0, 0, 0, 0, "Private DO 2"},
- { 0x0103, 0, 0, 0, 0, 0, 0, 0, "Private DO 3"},
- { 0x0104, 0, 0, 0, 0, 0, 0, 0, "Private DO 4"},
+ { 0x0101, 0, 0, 0, 0, 0, 0, 2, "Private DO 1"},
+ { 0x0102, 0, 0, 0, 0, 0, 0, 2, "Private DO 2"},
+ { 0x0103, 0, 0, 0, 0, 0, 0, 2, "Private DO 3"},
+ { 0x0104, 0, 0, 0, 0, 0, 0, 2, "Private DO 4"},
{ 0x7F21, 1, 0, 1, 0, 0, 0, 1, "Cardholder certificate"},
/* V3.0 */
{ 0x7F74, 0, 0, 1, 0, 0, 0, 0, "General Feature Management"},
@@ -185,18 +188,25 @@ struct app_local_s {
/* Keep track of extended card capabilities. */
struct
{
- unsigned int is_v2:1; /* This is a v2.0 compatible card. */
- unsigned int sm_supported:1; /* Secure Messaging is supported. */
+ unsigned int is_v2:1; /* Compatible to v2 or later. */
+ unsigned int extcap_v3:1; /* Extcap is in v3 format. */
+ unsigned int has_button:1; /* Has confirmation button or not. */
+
+ unsigned int sm_supported:1; /* Secure Messaging is supported. */
unsigned int get_challenge:1;
unsigned int key_import:1;
unsigned int change_force_chv:1;
unsigned int private_dos:1;
unsigned int algo_attr_change:1; /* Algorithm attributes changeable. */
- unsigned int has_decrypt:1; /* Support symmetric decryption. */
- unsigned int has_button:1;
- unsigned int sm_algo:2; /* Symmetric crypto algo for SM. */
+ unsigned int has_decrypt:1; /* Support symmetric decryption. */
+ unsigned int kdf_do:1; /* Support KDF DOs. */
+
+ unsigned int sm_algo:2; /* Symmetric crypto algo for SM. */
+ unsigned int pin_blk2:1; /* PIN block 2 format supported. */
+ unsigned int mse:1; /* MSE command supported. */
unsigned int max_certlen_3:16;
- unsigned int max_get_challenge:16; /* Maximum size for get_challenge. */
+ unsigned int max_get_challenge:16; /* Maximum size for get_challenge. */
+ unsigned int max_special_do:16; /* Maximum size for special DOs. */
} extcap;
/* Flags used to control the application. */
@@ -323,7 +333,14 @@ 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;
+ {
+ if (try_extlen == 1)
+ exmode = app->app_local->extcap.max_certlen_3;
+ else if (try_extlen == 2 && app->app_local->extcap.extcap_v3)
+ exmode = app->app_local->extcap.max_special_do;
+ else
+ exmode = 0;
+ }
else
exmode = 0;
@@ -4740,7 +4757,14 @@ do_check_pin (app_t app, const char *keyidstr,
static void
show_caps (struct app_local_s *s)
{
- log_info ("Version-2 ......: %s\n", s->extcap.is_v2? "yes":"no");
+ log_info ("Version-2+ .....: %s\n", s->extcap.is_v2? "yes":"no");
+ log_info ("Extcap-v3 ......: %s\n", s->extcap.extcap_v3? "yes":"no");
+ log_info ("Button .........: %s\n", s->extcap.has_button? "yes":"no");
+
+ log_info ("SM-Support .....: %s", s->extcap.sm_supported? "yes":"no");
+ if (s->extcap.sm_supported)
+ log_printf (" (%s)", s->extcap.sm_algo==2? "3DES":
+ (s->extcap.sm_algo==2? "AES-128" : "AES-256"));
log_info ("Get-Challenge ..: %s", s->extcap.get_challenge? "yes":"no");
if (s->extcap.get_challenge)
log_printf (" (%u bytes max)", s->extcap.max_get_challenge);
@@ -4748,16 +4772,18 @@ show_caps (struct app_local_s *s)
log_info ("Change-Force-PW1: %s\n", s->extcap.change_force_chv? "yes":"no");
log_info ("Private-DOs ....: %s\n", s->extcap.private_dos? "yes":"no");
log_info ("Algo-Attr-Change: %s\n", s->extcap.algo_attr_change? "yes":"no");
- log_info ("SM-Support .....: %s", s->extcap.sm_supported? "yes":"no");
- if (s->extcap.sm_supported)
- log_printf (" (%s)", s->extcap.sm_algo==2? "3DES":
- (s->extcap.sm_algo==2? "AES-128" : "AES-256"));
+ log_info ("Symmetric Crypto: %s\n", s->extcap.has_decrypt? "yes":"no");
+ log_info ("KDF-Support ....: %s\n", s->extcap.kdf_do? "yes":"no");
log_info ("Max-Cert3-Len ..: %u\n", s->extcap.max_certlen_3);
+ if (s->extcap.extcap_v3)
+ {
+ log_info ("PIN-Block-2 ....: %s\n", s->extcap.pin_blk2? "yes":"no");
+ log_info ("MSE-Support ....: %s\n", s->extcap.mse? "yes":"no");
+ log_info ("Max-Special-DOs : %u\n", s->extcap.max_special_do);
+ }
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);
- log_info ("Symmetric crypto: %s\n", s->extcap.has_decrypt? "yes":"no");
- log_info ("Button..........: %s\n", s->extcap.has_button? "yes":"no");
+ log_info ("Status-Indicator: %02X\n", s->status_indicator);
log_info ("GnuPG-No-Sync ..: %s\n", s->flags.no_sync? "yes":"no");
log_info ("GnuPG-Def-PW2 ..: %s\n", s->flags.def_chv2? "yes":"no");
@@ -5006,6 +5032,8 @@ app_select_openpgp (app_t app)
if (app->card_version >= 0x0200)
app->app_local->extcap.is_v2 = 1;
+ if (app->card_version >= 0x0300)
+ app->app_local->extcap.extcap_v3 = 1;
/* Read the historical bytes. */
relptr = get_one_do (app, 0x5f52, &buffer, &buflen, NULL);
@@ -5048,14 +5076,24 @@ app_select_openpgp (app_t app)
app->app_local->extcap.private_dos = !!(*buffer & 0x08);
app->app_local->extcap.algo_attr_change = !!(*buffer & 0x04);
app->app_local->extcap.has_decrypt = !!(*buffer & 0x02);
+ app->app_local->extcap.kdf_do = !!(*buffer & 0x01);
}
if (buflen >= 10)
{
- /* Available with v2 cards. */
+ /* Available with cards of v2 or later. */
app->app_local->extcap.sm_algo = buffer[1];
app->app_local->extcap.max_get_challenge
= (buffer[2] << 8 | buffer[3]);
app->app_local->extcap.max_certlen_3 = (buffer[4] << 8 | buffer[5]);
+
+ /* Interpretation is different between v2 and v3, unfortunately. */
+ if (app->app_local->extcap.extcap_v3)
+ {
+ app->app_local->extcap.max_special_do
+ = (buffer[6] << 8 | buffer[7]);
+ app->app_local->extcap.pin_blk2 = !!(buffer[8] & 0x01);
+ app->app_local->extcap.mse= !!(buffer[9] & 0x01);
+ }
}
xfree (relptr);
diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c
index fbbd157..9c22f51 100644
--- a/scd/ccid-driver.c
+++ b/scd/ccid-driver.c
@@ -1228,7 +1228,12 @@ ccid_get_reader_list (void)
if (!initialized_usb)
{
- libusb_init (NULL);
+ int rc;
+ if ((rc = libusb_init (NULL)))
+ {
+ DEBUGOUT_1 ("usb_init failed: %s.\n", libusb_error_name (rc));
+ return NULL;
+ }
initialized_usb = 1;
}
@@ -1292,9 +1297,17 @@ ccid_dev_scan (int *idx_max_p, struct ccid_dev_table **t_p)
int idx = 0;
int err = 0;
+ *idx_max_p = 0;
+ *t_p = NULL;
+
if (!initialized_usb)
{
- libusb_init (NULL);
+ int rc;
+ if ((rc = libusb_init (NULL)))
+ {
+ DEBUGOUT_1 ("usb_init failed: %s.\n", libusb_error_name (rc));
+ return gpg_error (GPG_ERR_ENODEV);
+ }
initialized_usb = 1;
}
@@ -1373,8 +1386,6 @@ ccid_dev_scan (int *idx_max_p, struct ccid_dev_table **t_p)
if (err)
{
- *idx_max_p = 0;
- *t_p = NULL;
for (i = 0; i < idx; i++)
{
free (ccid_dev_table[idx].ifcdesc_extra);
@@ -1476,6 +1487,7 @@ intr_cb (struct libusb_transfer *transfer)
{
DEBUGOUT ("CCID: card removed\n");
handle->powered_off = 1;
+ scd_kick_the_loop ();
}
else
{
@@ -1490,9 +1502,8 @@ intr_cb (struct libusb_transfer *transfer)
device_removed:
DEBUGOUT ("CCID: device removed\n");
handle->powered_off = 1;
+ scd_kick_the_loop ();
}
-
- scd_kick_the_loop ();
}
static void
@@ -2032,8 +2043,11 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
* Possibly, it was forcibly suspended and resumed.
*/
DEBUGOUT ("CCID: card inactive/removed\n");
- handle->powered_off = 1;
- scd_kick_the_loop ();
+ if (handle->transfer == NULL)
+ {
+ handle->powered_off = 1;
+ scd_kick_the_loop ();
+ }
}
return rc;
diff --git a/scd/scdaemon.c b/scd/scdaemon.c
index 26e89dd..60d539d 100644
--- a/scd/scdaemon.c
+++ b/scd/scdaemon.c
@@ -908,14 +908,15 @@ main (int argc, char **argv )
sigaction (SIGPIPE, &sa, NULL);
}
- if (chdir("/"))
+#endif /*!HAVE_W32_SYSTEM*/
+
+ if (gnupg_chdir (gnupg_daemon_rootdir ()))
{
- log_error ("chdir to / failed: %s\n", strerror (errno));
+ log_error ("chdir to '%s' failed: %s\n",
+ gnupg_daemon_rootdir (), strerror (errno));
exit (1);
}
-#endif /*!HAVE_W32_SYSTEM*/
-
handle_connections (fd);
close (fd);
diff --git a/sm/call-agent.c b/sm/call-agent.c
index 0e47c14..ba8fb12 100644
--- a/sm/call-agent.c
+++ b/sm/call-agent.c
@@ -171,6 +171,25 @@ start_agent (ctrl_t ctrl)
str_pinentry_mode (opt.pinentry_mode),
gpg_strerror (rc));
}
+
+ /* In DE_VS mode under Windows we require that the JENT RNG
+ * is active. */
+#ifdef HAVE_W32_SYSTEM
+ if (!rc && opt.compliance == CO_DE_VS)
+ {
+ if (assuan_transact (agent_ctx, "GETINFO jent_active",
+ NULL, NULL, NULL, NULL, NULL, NULL))
+ {
+ rc = gpg_error (GPG_ERR_FORBIDDEN);
+ log_error (_("%s is not compliant with %s mode\n"),
+ GPG_AGENT_NAME,
+ gnupg_compliance_option_string (opt.compliance));
+ gpgsm_status_with_error (ctrl, STATUS_ERROR,
+ "random-compliance", rc);
+ }
+ }
+#endif /*HAVE_W32_SYSTEM*/
+
}
}
diff --git a/sm/decrypt.c b/sm/decrypt.c
index 976bd12..cdce1d4 100644
--- a/sm/decrypt.c
+++ b/sm/decrypt.c
@@ -32,6 +32,7 @@
#include "keydb.h"
#include "../common/i18n.h"
+#include "../common/compliance.h"
struct decrypt_filter_parm_s
{
@@ -41,7 +42,7 @@ struct decrypt_filter_parm_s
gcry_cipher_hd_t hd;
char iv[16];
size_t ivlen;
- int any_data; /* dod we push anything through the filter at all? */
+ int any_data; /* did we push anything through the filter at all? */
unsigned char lastblock[16]; /* to strip the padding we have to
keep this one */
char helpblock[16]; /* needed because there is no block buffering in
@@ -325,6 +326,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp)
int algo, mode;
const char *algoid;
int any_key = 0;
+ int is_de_vs; /* Computed compliance with CO_DE_VS. */
audit_log (ctrl->audit, AUDIT_GOT_DATA);
@@ -356,6 +358,20 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp)
goto leave;
}
+ /* Check compliance. */
+ if (! gnupg_cipher_is_allowed (opt.compliance, 0, algo, mode))
+ {
+ log_error (_("cipher algorithm '%s'"
+ " may not be used in %s mode\n"),
+ gcry_cipher_algo_name (algo),
+ gnupg_compliance_option_string (opt.compliance));
+ rc = gpg_error (GPG_ERR_CIPHER_ALGO);
+ goto leave;
+ }
+
+ /* For CMS, CO_DE_VS demands CBC mode. */
+ is_de_vs = gnupg_cipher_is_compliant (CO_DE_VS, algo, mode);
+
audit_log_i (ctrl->audit, AUDIT_DATA_CIPHER_ALGO, algo);
dfparm.algo = algo;
dfparm.mode = mode;
@@ -460,7 +476,37 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp)
hexkeygrip = gpgsm_get_keygrip_hexstring (cert);
desc = gpgsm_format_keydesc (cert);
+ {
+ unsigned int nbits;
+ int pk_algo = gpgsm_get_key_algo_info (cert, &nbits);
+
+ /* Print compliance warning. */
+ if (! gnupg_pk_is_compliant (opt.compliance,
+ pk_algo, NULL, nbits, NULL))
+ {
+ char kidstr[10+1];
+
+ snprintf (kidstr, sizeof kidstr, "0x%08lX",
+ gpgsm_get_short_fingerprint (cert, NULL));
+ log_info
+ (_("Note: key %s is not suitable for encryption"
+ " in %s mode\n"),
+ kidstr,
+ gnupg_compliance_option_string (opt.compliance));
+ }
+
+ /* Check that all certs are compliant with CO_DE_VS. */
+ is_de_vs =
+ (is_de_vs
+ && gnupg_pk_is_compliant (CO_DE_VS, pk_algo, NULL,
+ nbits, NULL));
+ }
+
oops:
+ if (rc)
+ /* We cannot check compliance of certs that we
+ * don't have. */
+ is_de_vs = 0;
xfree (issuer);
xfree (serial);
ksba_cert_release (cert);
@@ -489,6 +535,11 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp)
ksba_writer_set_filter (writer,
decrypt_filter,
&dfparm);
+
+ if (is_de_vs)
+ gpgsm_status (ctrl, STATUS_DECRYPTION_COMPLIANCE_MODE,
+ gnupg_status_compliance_flag (CO_DE_VS));
+
}
audit_log_ok (ctrl->audit, AUDIT_RECP_RESULT, rc);
}
diff --git a/sm/encrypt.c b/sm/encrypt.c
index c43a9e6..6213a66 100644
--- a/sm/encrypt.c
+++ b/sm/encrypt.c
@@ -33,6 +33,7 @@
#include "keydb.h"
#include "../common/i18n.h"
+#include "../common/compliance.h"
struct dek_s {
@@ -312,6 +313,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp)
estream_t data_fp = NULL;
certlist_t cl;
int count;
+ int compliant;
memset (&encparm, 0, sizeof encparm);
@@ -405,6 +407,29 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp)
goto leave;
}
+ /* Check compliance. */
+ if (!gnupg_cipher_is_allowed
+ (opt.compliance, 1, gcry_cipher_map_name (opt.def_cipher_algoid),
+ gcry_cipher_mode_from_oid (opt.def_cipher_algoid)))
+ {
+ log_error (_("cipher algorithm '%s' may not be used in %s mode\n"),
+ opt.def_cipher_algoid,
+ gnupg_compliance_option_string (opt.compliance));
+ rc = gpg_error (GPG_ERR_CIPHER_ALGO);
+ goto leave;
+ }
+
+ if (!gnupg_rng_is_compliant (opt.compliance))
+ {
+ rc = gpg_error (GPG_ERR_FORBIDDEN);
+ log_error (_("%s is not compliant with %s mode\n"),
+ "RNG",
+ gnupg_compliance_option_string (opt.compliance));
+ gpgsm_status_with_error (ctrl, STATUS_ERROR,
+ "random-compliance", rc);
+ goto leave;
+ }
+
/* Create a session key */
dek = xtrycalloc_secure (1, sizeof *dek);
if (!dek)
@@ -442,11 +467,36 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp)
audit_log_s (ctrl->audit, AUDIT_SESSION_KEY, dek->algoid);
+ compliant = gnupg_cipher_is_compliant (CO_DE_VS, dek->algo,
+ GCRY_CIPHER_MODE_CBC);
+
/* Gather certificates of recipients, encrypt the session key for
each and store them in the CMS object */
for (recpno = 0, cl = recplist; cl; recpno++, cl = cl->next)
{
unsigned char *encval;
+ unsigned int nbits;
+ int pk_algo;
+
+ /* Check compliance. */
+ pk_algo = gpgsm_get_key_algo_info (cl->cert, &nbits);
+ if (!gnupg_pk_is_compliant (opt.compliance, pk_algo, NULL, nbits, NULL))
+ {
+ char kidstr[10+1];
+
+ snprintf (kidstr, sizeof kidstr, "0x%08lX",
+ gpgsm_get_short_fingerprint (cl->cert, NULL));
+ log_info (_("WARNING: key %s is not suitable for encryption"
+ " in %s mode\n"),
+ kidstr,
+ gnupg_compliance_option_string (opt.compliance));
+ }
+
+ /* Fixme: When adding ECC we need to provide the curvename and
+ * the key to gnupg_pk_is_compliant. */
+ if (compliant
+ && !gnupg_pk_is_compliant (CO_DE_VS, pk_algo, NULL, nbits, NULL))
+ compliant = 0;
rc = encrypt_dek (dek, cl->cert, &encval);
if (rc)
@@ -480,6 +530,10 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp)
}
}
+ if (compliant)
+ gpgsm_status (ctrl, STATUS_ENCRYPTION_COMPLIANCE_MODE,
+ gnupg_status_compliance_flag (CO_DE_VS));
+
/* Main control loop for encryption. */
recpno = 0;
do
diff --git a/sm/gpgsm.c b/sm/gpgsm.c
index cb181e8..10eff0a 100644
--- a/sm/gpgsm.c
+++ b/sm/gpgsm.c
@@ -41,6 +41,7 @@
#include "../common/gc-opt-flags.h"
#include "../common/asshelp.h"
#include "../common/init.h"
+#include "../common/compliance.h"
#ifndef O_BINARY
@@ -946,6 +947,9 @@ main ( int argc, char **argv)
dotlock_create (NULL, 0); /* Register lockfile cleanup. */
+ /* Tell the compliance module who we are. */
+ gnupg_initialize_compliance (GNUPG_MODULE_NAME_GPGSM);
+
opt.autostart = 1;
opt.session_env = session_env_new ();
if (!opt.session_env)
@@ -1443,7 +1447,19 @@ main ( int argc, char **argv)
case oNoAutostart: opt.autostart = 0; break;
case oCompliance:
- /* Dummy option for now. */
+ {
+ struct gnupg_compliance_option compliance_options[] =
+ {
+ { "de-vs", CO_DE_VS }
+ };
+ int compliance = gnupg_parse_compliance_option (pargs.r.ret_str,
+ compliance_options,
+ DIM (compliance_options),
+ opt.quiet);
+ if (compliance < 0)
+ gpgsm_exit (1);
+ opt.compliance = compliance;
+ }
break;
default:
@@ -1598,6 +1614,44 @@ main ( int argc, char **argv)
}
}
+ /* Check our chosen algorithms against the list of allowed
+ * algorithms in the current compliance mode, and fail hard if it is
+ * not. This is us being nice to the user informing her early that
+ * the chosen algorithms are not available. We also check and
+ * enforce this right before the actual operation. */
+ if (! gnupg_cipher_is_allowed (opt.compliance,
+ cmd == aEncr || cmd == aSignEncr,
+ gcry_cipher_map_name (opt.def_cipher_algoid),
+ GCRY_CIPHER_MODE_NONE)
+ && ! gnupg_cipher_is_allowed (opt.compliance,
+ cmd == aEncr || cmd == aSignEncr,
+ gcry_cipher_mode_from_oid
+ (opt.def_cipher_algoid),
+ GCRY_CIPHER_MODE_NONE))
+ log_error (_("cipher algorithm '%s' may not be used in %s mode\n"),
+ opt.def_cipher_algoid,
+ gnupg_compliance_option_string (opt.compliance));
+
+ if (forced_digest_algo
+ && ! gnupg_digest_is_allowed (opt.compliance,
+ cmd == aSign
+ || cmd == aSignEncr
+ || cmd == aClearsign,
+ opt.forced_digest_algo))
+ log_error (_("digest algorithm '%s' may not be used in %s mode\n"),
+ forced_digest_algo,
+ gnupg_compliance_option_string (opt.compliance));
+
+ if (extra_digest_algo
+ && ! gnupg_digest_is_allowed (opt.compliance,
+ cmd == aSign
+ || cmd == aSignEncr
+ || cmd == aClearsign,
+ opt.extra_digest_algo))
+ log_error (_("digest algorithm '%s' may not be used in %s mode\n"),
+ forced_digest_algo,
+ gnupg_compliance_option_string (opt.compliance));
+
if (log_get_errorcount(0))
gpgsm_exit(2);
diff --git a/sm/gpgsm.h b/sm/gpgsm.h
index df96770..8c1f520 100644
--- a/sm/gpgsm.h
+++ b/sm/gpgsm.h
@@ -34,6 +34,7 @@
#include "../common/audit.h"
#include "../common/session-env.h"
#include "../common/ksba-io-support.h"
+#include "../common/compliance.h"
#define MAX_DIGEST_LEN 64
@@ -144,6 +145,7 @@ struct
OID per string. */
strlist_t ignored_cert_extensions;
+ enum gnupg_compliance_mode compliance;
} opt;
/* Debug values and macros. */
diff --git a/sm/keylist.c b/sm/keylist.c
index 13de45d..abec049 100644
--- a/sm/keylist.c
+++ b/sm/keylist.c
@@ -36,6 +36,7 @@
#include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
#include "../common/i18n.h"
#include "../common/tlv.h"
+#include "../common/compliance.h"
struct list_external_parm_s
{
@@ -351,8 +352,8 @@ email_kludge (const char *name)
static void
print_compliance_flags (int algo, unsigned int nbits, estream_t fp)
{
- if (algo == GCRY_PK_RSA && nbits >= 2048)
- es_fputs ("23", fp);
+ if (gnupg_pk_is_compliant (CO_DE_VS, algo, NULL, nbits, NULL))
+ es_fputs (gnupg_status_compliance_flag (CO_DE_VS), fp);
}
diff --git a/sm/sign.c b/sm/sign.c
index e65562d..24ecad3 100644
--- a/sm/sign.c
+++ b/sm/sign.c
@@ -339,6 +339,17 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
goto leave;
}
+ if (!gnupg_rng_is_compliant (opt.compliance))
+ {
+ rc = gpg_error (GPG_ERR_FORBIDDEN);
+ log_error (_("%s is not compliant with %s mode\n"),
+ "RNG",
+ gnupg_compliance_option_string (opt.compliance));
+ gpgsm_status_with_error (ctrl, STATUS_ERROR,
+ "random-compliance", rc);
+ goto leave;
+ }
+
ctrl->pem_name = "SIGNED MESSAGE";
rc = gnupg_ksba_create_writer
(&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0)
@@ -460,6 +471,35 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
break;
}
cl->hash_algo_oid = oid;
+
+ /* Check compliance. */
+ if (! gnupg_digest_is_allowed (opt.compliance, 1, cl->hash_algo))
+ {
+ log_error (_("digest algorithm '%s' may not be used in %s mode\n"),
+ gcry_md_algo_name (cl->hash_algo),
+ gnupg_compliance_option_string (opt.compliance));
+ err = gpg_error (GPG_ERR_DIGEST_ALGO);
+ goto leave;
+ }
+
+ {
+ unsigned int nbits;
+ int pk_algo = gpgsm_get_key_algo_info (cl->cert, &nbits);
+
+ if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_SIGNING, pk_algo,
+ NULL, nbits, NULL))
+ {
+ char kidstr[10+1];
+
+ snprintf (kidstr, sizeof kidstr, "0x%08lX",
+ gpgsm_get_short_fingerprint (cl->cert, NULL));
+ log_error (_("key %s may not be used for signing in %s mode\n"),
+ kidstr,
+ gnupg_compliance_option_string (opt.compliance));
+ err = gpg_error (GPG_ERR_PUBKEY_ALGO);
+ goto leave;
+ }
+ }
}
if (opt.verbose)
diff --git a/sm/verify.c b/sm/verify.c
index 6c034e6..10b3f43 100644
--- a/sm/verify.c
+++ b/sm/verify.c
@@ -33,6 +33,7 @@
#include "keydb.h"
#include "../common/i18n.h"
+#include "../common/compliance.h"
static char *
strtimestamp_r (ksba_isotime_t atime)
@@ -341,16 +342,11 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
&msgdigest, &msgdigestlen);
if (!rc)
{
- size_t is_enabled;
-
algoid = ksba_cms_get_digest_algo (cms, signer);
algo = gcry_md_map_name (algoid);
if (DBG_X509)
log_debug ("signer %d - digest algo: %d\n", signer, algo);
- is_enabled = sizeof algo;
- if ( gcry_md_info (data_md, GCRYCTL_IS_ALGO_ENABLED,
- &algo, &is_enabled)
- || !is_enabled)
+ if (! gcry_md_is_enabled (data_md, algo))
{
log_error ("digest algo %d (%s) has not been enabled\n",
algo, algoid?algoid:"");
@@ -454,6 +450,39 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
goto next_signer;
}
+ /* Check compliance. */
+ {
+ unsigned int nbits;
+ int pk_algo = gpgsm_get_key_algo_info (cert, &nbits);
+
+ if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_VERIFICATION,
+ pk_algo, NULL, nbits, NULL))
+ {
+ char kidstr[10+1];
+
+ snprintf (kidstr, sizeof kidstr, "0x%08lX",
+ gpgsm_get_short_fingerprint (cert, NULL));
+ log_error (_("key %s may not be used for signing in %s mode\n"),
+ kidstr,
+ gnupg_compliance_option_string (opt.compliance));
+ goto next_signer;
+ }
+
+ if (! gnupg_digest_is_allowed (opt.compliance, 0, sigval_hash_algo))
+ {
+ log_error (_("digest algorithm '%s' may not be used in %s mode\n"),
+ gcry_md_algo_name (sigval_hash_algo),
+ gnupg_compliance_option_string (opt.compliance));
+ goto next_signer;
+ }
+
+ /* Check compliance with CO_DE_VS. */
+ if (gnupg_pk_is_compliant (CO_DE_VS, pk_algo, NULL, nbits, NULL)
+ && gnupg_digest_is_compliant (CO_DE_VS, sigval_hash_algo))
+ gpgsm_status (ctrl, STATUS_VERIFICATION_COMPLIANCE_MODE,
+ gnupg_status_compliance_flag (CO_DE_VS));
+ }
+
log_info (_("Signature made "));
if (*sigtime)
dump_isotime (sigtime);
@@ -636,7 +665,6 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
(verifyflags & VALIDATE_FLAG_CHAIN_MODEL)?
"0 chain": "0 shell");
-
next_signer:
rc = 0;
xfree (issuer);
diff --git a/tests/fake-pinentries/README.txt b/tests/fake-pinentries/README.txt
index 9272ae5..0654f56 100644
--- a/tests/fake-pinentries/README.txt
+++ b/tests/fake-pinentries/README.txt
@@ -35,4 +35,4 @@ Troubleshooting
If you have any trouble with this technique, please drop a line to the
GnuPG development mailing list <gnupg-devel@gnupg.org> or open a
-report on the GnuPG bug tracker at https://bugs.gnupg.org/gnupg
+report on the GnuPG bug tracker at https://dev.gnupg.org/gnupg
diff --git a/tests/gpgme/gpgme-defs.scm b/tests/gpgme/gpgme-defs.scm
index e24db25..0de589f 100644
--- a/tests/gpgme/gpgme-defs.scm
+++ b/tests/gpgme/gpgme-defs.scm
@@ -66,7 +66,9 @@
(string-append "agent-program " (tool 'gpg-agent) "|--debug-quick-random\n"))
(create-file
"gpg-agent.conf"
- (string-append "pinentry-program " (tool 'pinentry)))
+ (string-append "pinentry-program " (tool 'pinentry))
+ (string-append "scdaemon-program " (tool 'scdaemon))
+ )
(start-agent)
diff --git a/tests/gpgscm/ffi.c b/tests/gpgscm/ffi.c
index 3af3328..4c03ba6 100644
--- a/tests/gpgscm/ffi.c
+++ b/tests/gpgscm/ffi.c
@@ -915,6 +915,8 @@ do_wait_processes (scheme *sc, pointer args)
retcodes);
if (err == GPG_ERR_GENERAL)
err = 0; /* Let the return codes speak. */
+ if (err == GPG_ERR_TIMEOUT)
+ err = 0; /* We may have got some results. */
for (i = 0; i < count; i++)
retcodes_list =
diff --git a/tests/gpgscm/ffi.scm b/tests/gpgscm/ffi.scm
index 3f2e553..051c2c2 100644
--- a/tests/gpgscm/ffi.scm
+++ b/tests/gpgscm/ffi.scm
@@ -36,8 +36,7 @@
(define (ffi-fail name args message)
(let ((args' (open-output-string)))
(write (cons (string->symbol name) args) args')
- (throw (string-append
- (get-output-string args') ": " message))))
+ (throw (get-output-string args') message)))
;; Pseudo-definitions for foreign functions. Evaluates to no code,
;; but serves as documentation.
diff --git a/tests/gpgscm/init.scm b/tests/gpgscm/init.scm
index 3769ed0..66bec0f 100644
--- a/tests/gpgscm/init.scm
+++ b/tests/gpgscm/init.scm
@@ -605,17 +605,17 @@
;; This is used by the vm to throw exceptions.
(define (throw' message args history)
(cond
- ((more-handlers?)
- ((pop-handler) message args history))
((and args (list? args) (= 2 (length args))
(equal? *interpreter-exit* (car args)))
(*run-atexit-handlers*)
(quit (cadr args)))
+ ((more-handlers?)
+ ((pop-handler) message args history))
(else
(display message)
(when (and args (not (null? args)))
(display ": ")
- (if (string? (car args))
+ (if (and (pair? args) (string? (car args)))
(begin (display (car args))
(unless (null? (cdr args))
(newline)
diff --git a/tests/gpgscm/main.c b/tests/gpgscm/main.c
index e4b535e..5540ac3 100644
--- a/tests/gpgscm/main.c
+++ b/tests/gpgscm/main.c
@@ -124,6 +124,19 @@ my_strusage( int level )
}
+
+static int
+path_absolute_p (const char *p)
+{
+#if _WIN32
+ return ((strlen (p) > 2 && p[1] == ':' && (p[2] == '\\' || p[2] == '/'))
+ || p[0] == '\\' || p[0] == '/');
+#else
+ return p[0] == '/';
+#endif
+}
+
+
/* Load the Scheme program from FILE_NAME. If FILE_NAME is not an
absolute path, and LOOKUP_IN_PATH is given, then it is qualified
with the values in scmpath until the file is found. */
@@ -139,9 +152,9 @@ load (scheme *sc, char *file_name,
FILE *h = NULL;
use_path =
- lookup_in_path && ! (file_name[0] == '/' || scmpath_len == 0);
+ lookup_in_path && ! (path_absolute_p (file_name) || scmpath_len == 0);
- if (file_name[0] == '/' || lookup_in_cwd || scmpath_len == 0)
+ if (path_absolute_p (file_name) || lookup_in_cwd || scmpath_len == 0)
{
h = fopen (file_name, "r");
if (! h)
@@ -182,7 +195,7 @@ load (scheme *sc, char *file_name,
"of the Scheme library.\n");
goto leave;
}
- if (verbose > 1)
+ if (verbose > 2)
fprintf (stderr, "Loading %s...\n", qualified_name);
#if HAVE_MMAP
diff --git a/tests/gpgscm/repl.scm b/tests/gpgscm/repl.scm
index 84454dc..833ec0d 100644
--- a/tests/gpgscm/repl.scm
+++ b/tests/gpgscm/repl.scm
@@ -55,3 +55,15 @@
(define (interactive-repl . environment)
(repl (lambda (p) (prompt-append-prefix "gpgscm " p))
(if (null? environment) (interaction-environment) (car environment))))
+
+;; Ask a yes/no question.
+(define (prompt-yes-no? question default)
+ (let ((answer (prompt (string-append question "? ["
+ (if default "Y/n" "y/N") "] "))))
+ (cond
+ ((= 0 (string-length answer))
+ default)
+ ((or (equal? "y" answer) (equal? "Y" answer))
+ #t)
+ (else
+ #f))))
diff --git a/tests/gpgscm/scheme.c b/tests/gpgscm/scheme.c
index 26bb5a5..f5e52fc 100644
--- a/tests/gpgscm/scheme.c
+++ b/tests/gpgscm/scheme.c
@@ -3451,9 +3451,10 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
double dd;
#endif
int (*comp_func)(num, num) = NULL;
- const struct op_code_info *pcd = &dispatch_table[op];
+ const struct op_code_info *pcd;
dispatch:
+ pcd = &dispatch_table[op];
if (pcd->name[0] != 0) { /* if built-in function, check arguments */
char msg[STRBUFFSIZE];
if (! check_arguments (sc, pcd, msg, sizeof msg)) {
@@ -3564,7 +3565,7 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
if (x != sc->NIL) {
s_return(sc,slot_value_in_env(x));
} else {
- Error_1(sc,"eval: unbound variable:", sc->code);
+ Error_1(sc, "eval: unbound variable", sc->code);
}
} else if (is_pair(sc->code)) {
if (is_syntax(x = car(sc->code))) { /* SYNTAX */
@@ -3676,7 +3677,7 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
for (x = car(closure_code(sc->code)), y = sc->args;
is_pair(x); x = cdr(x), y = cdr(y)) {
if (y == sc->NIL) {
- Error_1(sc, "not enough arguments, missing:", x);
+ Error_1(sc, "not enough arguments, missing", x);
} else if (is_symbol(car(x))) {
new_slot_in_env(sc, car(x), car(y));
} else {
@@ -3691,7 +3692,7 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
} else if (is_symbol(x))
new_slot_in_env(sc, x, y);
else {
- Error_1(sc,"syntax error in closure: not a symbol:", x);
+ Error_1(sc, "syntax error in closure: not a symbol", x);
}
sc->code = cdr(closure_code(sc->code));
sc->args = sc->NIL;
@@ -3804,7 +3805,7 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
set_slot_in_env(sc, y, sc->value);
s_return(sc,sc->value);
} else {
- Error_1(sc,"set!: unbound variable:", sc->code);
+ Error_1(sc, "set!: unbound variable", sc->code);
}
@@ -3854,7 +3855,7 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
if (is_pair(sc->code)) { /* continue */
if (!is_pair(car(sc->code)) || !is_pair(cdar(sc->code))) {
gc_enable(sc);
- Error_1(sc, "Bad syntax of binding spec in let :",
+ Error_1(sc, "Bad syntax of binding spec in let",
car(sc->code));
}
s_save(sc,OP_LET1, sc->args, cdr(sc->code));
@@ -3880,9 +3881,9 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
if (is_symbol(car(sc->code))) { /* named let */
for (x = cadr(sc->code), sc->args = sc->NIL; x != sc->NIL; x = cdr(x)) {
if (!is_pair(x))
- Error_1(sc, "Bad syntax of binding in let :", x);
+ Error_1(sc, "Bad syntax of binding in let", x);
if (!is_list(sc, car(x)))
- Error_1(sc, "Bad syntax of binding in let :", car(x));
+ Error_1(sc, "Bad syntax of binding in let", car(x));
gc_disable(sc, 1);
sc->args = cons(sc, caar(x), sc->args);
gc_enable(sc);
@@ -3906,7 +3907,7 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
s_thread_to(sc,OP_BEGIN);
}
if(!is_pair(car(sc->code)) || !is_pair(caar(sc->code)) || !is_pair(cdaar(sc->code))) {
- Error_1(sc,"Bad syntax of binding spec in let* :",car(sc->code));
+ Error_1(sc, "Bad syntax of binding spec in let*", car(sc->code));
}
s_save(sc,OP_LET1AST, cdr(sc->code), car(sc->code));
sc->code = cadaar(sc->code);
@@ -3945,7 +3946,7 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
gc_enable(sc);
if (is_pair(sc->code)) { /* continue */
if (!is_pair(car(sc->code)) || !is_pair(cdar(sc->code))) {
- Error_1(sc, "Bad syntax of binding spec in letrec :",
+ Error_1(sc, "Bad syntax of binding spec in letrec",
car(sc->code));
}
s_save(sc,OP_LET1REC, sc->args, cdr(sc->code));
@@ -4164,7 +4165,7 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
} else if(modf(rvalue_unchecked(x),&dd)==0.0) {
s_return(sc,mk_integer(sc,ivalue(x)));
} else {
- Error_1(sc,"inexact->exact: not integral:",x);
+ Error_1(sc, "inexact->exact: not integral", x);
}
CASE(OP_EXP):
@@ -4424,7 +4425,7 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
}
}
if (pf < 0) {
- Error_1(sc, "string->atom: bad base:", cadr(sc->args));
+ Error_1(sc, "string->atom: bad base", cadr(sc->args));
} else if(*s=='#') /* no use of base! */ {
s_return(sc, mk_sharp_const(sc, s+1));
} else {
@@ -4465,7 +4466,7 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
}
}
if (pf < 0) {
- Error_1(sc, "atom->string: bad base:", cadr(sc->args));
+ Error_1(sc, "atom->string: bad base", cadr(sc->args));
} else if(is_number(x) || is_character(x) || is_string(x) || is_symbol(x)) {
char *p;
int len;
@@ -4473,7 +4474,7 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
gc_disable(sc, 1);
s_return_enable_gc(sc, mk_counted_string(sc, p, len));
} else {
- Error_1(sc, "atom->string: not an atom:", x);
+ Error_1(sc, "atom->string: not an atom", x);
}
}
@@ -4503,7 +4504,7 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
index=ivalue(cadr(sc->args));
if(index>=strlength(car(sc->args))) {
- Error_1(sc,"string-ref: out of bounds:",cadr(sc->args));
+ Error_1(sc, "string-ref: out of bounds", cadr(sc->args));
}
gc_disable(sc, 1);
@@ -4517,13 +4518,14 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
int c;
if(is_immutable(car(sc->args))) {
- Error_1(sc,"string-set!: unable to alter immutable string:",car(sc->args));
+ Error_1(sc, "string-set!: unable to alter immutable string",
+ car(sc->args));
}
str=strvalue(car(sc->args));
index=ivalue(cadr(sc->args));
if(index>=strlength(car(sc->args))) {
- Error_1(sc,"string-set!: out of bounds:",cadr(sc->args));
+ Error_1(sc, "string-set!: out of bounds", cadr(sc->args));
}
c=charvalue(caddr(sc->args));
@@ -4562,13 +4564,13 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
index0=ivalue(cadr(sc->args));
if(index0>strlength(car(sc->args))) {
- Error_1(sc,"substring: start out of bounds:",cadr(sc->args));
+ Error_1(sc, "substring: start out of bounds", cadr(sc->args));
}
if(cddr(sc->args)!=sc->NIL) {
index1=ivalue(caddr(sc->args));
if(index1>strlength(car(sc->args)) || index1<index0) {
- Error_1(sc,"substring: end out of bounds:",caddr(sc->args));
+ Error_1(sc, "substring: end out of bounds", caddr(sc->args));
}
} else {
index1=strlength(car(sc->args));
@@ -4583,7 +4585,7 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
pointer vec;
int len=list_length(sc,sc->args);
if(len<0) {
- Error_1(sc,"vector: not a proper list:",sc->args);
+ Error_1(sc, "vector: not a proper list", sc->args);
}
vec=mk_vector(sc,len);
if(sc->no_memory) { s_return(sc, sc->sink); }
@@ -4621,7 +4623,7 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
index=ivalue(cadr(sc->args));
if(index >= vector_length(car(sc->args))) {
- Error_1(sc,"vector-ref: out of bounds:",cadr(sc->args));
+ Error_1(sc, "vector-ref: out of bounds", cadr(sc->args));
}
s_return(sc,vector_elem(car(sc->args),index));
@@ -4631,12 +4633,13 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
int index;
if(is_immutable(car(sc->args))) {
- Error_1(sc,"vector-set!: unable to alter immutable vector:",car(sc->args));
+ Error_1(sc, "vector-set!: unable to alter immutable vector",
+ car(sc->args));
}
index=ivalue(cadr(sc->args));
if(index >= vector_length(car(sc->args))) {
- Error_1(sc,"vector-set!: out of bounds:",cadr(sc->args));
+ Error_1(sc, "vector-set!: out of bounds", cadr(sc->args));
}
set_vector_elem(car(sc->args),index,caddr(sc->args));
@@ -4979,7 +4982,7 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
s_thread_to(sc,OP_READ_INTERNAL);
}
if(!is_inport(car(sc->args))) {
- Error_1(sc,"read: not an input port:",car(sc->args));
+ Error_1(sc, "read: not an input port", car(sc->args));
}
if(car(sc->args)==sc->inport) {
s_thread_to(sc,OP_READ_INTERNAL);
@@ -5257,7 +5260,7 @@ Eval_Cycle(scheme *sc, enum scheme_opcodes op) {
CASE(OP_LIST_LENGTH): { /* length */ /* a.k */
long l = list_length(sc, car(sc->args));
if(l<0) {
- Error_1(sc,"length: not a list:",car(sc->args));
+ Error_1(sc, "length: not a list", car(sc->args));
}
gc_disable(sc, 1);
s_return_enable_gc(sc, mk_integer(sc, l));
diff --git a/tests/gpgscm/tests.scm b/tests/gpgscm/tests.scm
index eee8ce5..40ba7e3 100644
--- a/tests/gpgscm/tests.scm
+++ b/tests/gpgscm/tests.scm
@@ -192,6 +192,16 @@
(define (in-srcdir . names)
(canonical-path (apply path-join (cons (getenv "abs_top_srcdir") names))))
+;; Split a list of paths.
+(define (pathsep-split s)
+ (string-split s *pathsep*))
+
+;; Join a list of paths.
+(define (pathsep-join paths)
+ (foldr (lambda (a b) (string-append a (string *pathsep*) b))
+ (car paths)
+ (cdr paths)))
+
;; Try to find NAME in PATHS. Returns the full path name on success,
;; or raises an error.
(define (path-expand name paths)
@@ -209,7 +219,7 @@
;; (load (with-path "library.scm"))
(define (with-path name)
(catch name
- (path-expand name (string-split (getenv "GPGSCM_PATH") *pathsep*))))
+ (path-expand name (pathsep-split (getenv "GPGSCM_PATH")))))
(define (basename path)
(let ((i (string-index path #\/)))
@@ -498,29 +508,98 @@
;; The main test framework.
;;
+(define semaphore
+ (package
+ (define (new n)
+ (package
+ (define (acquire!?)
+ (if (> n 0)
+ (begin
+ (set! n (- n 1))
+ #t)
+ #f))
+ (define (release!)
+ (set! n (+ n 1)))))))
+
;; A pool of tests.
(define test-pool
(package
- (define (new procs)
+ (define (new n)
(package
+ ;; A semaphore to restrict the number of spawned processes.
+ (define sem (semaphore::new n))
+
+ ;; A list of enqueued, but not yet run tests.
+ (define enqueued '())
+
+ ;; A list of running or finished processes.
+ (define procs '())
+
(define (add test)
- (set! procs (cons test procs))
+ (if (test::started?)
+ (set! procs (cons test procs))
+ (if (sem::acquire!?)
+ (add (test::run-async))
+ (set! enqueued (cons test enqueued))))
(current-environment))
+
+ ;; Pop the last of the enqueued tests off the fifo queue.
+ (define (pop-test!)
+ (let ((i (length enqueued)))
+ (assert (> i 0))
+ (cond
+ ((= i 1)
+ (let ((test (car enqueued)))
+ (set! enqueued '())
+ test))
+ (else
+ (let* ((tail (list-tail enqueued (- i 2)))
+ (test (cadr tail)))
+ (set-cdr! tail '())
+ (assert (= (length enqueued) (- i 1)))
+ test)))))
+
(define (pid->test pid)
(let ((t (filter (lambda (x) (= pid x::pid)) procs)))
(if (null? t) #f (car t))))
(define (wait)
+ (if (null? enqueued)
+ ;; If no tests are enqueued, we can just block until all
+ ;; of them finished.
+ (wait' #t)
+ ;; Otherwise, we must not block, but give some tests the
+ ;; chance to finish so that we can start new ones.
+ (begin
+ (wait' #f)
+ (usleep (/ 1000000 10))
+ (wait))))
+ (define (wait' hang)
(let ((unfinished (filter (lambda (t) (not t::retcode)) procs)))
(if (null? unfinished)
(current-environment)
(let ((names (map (lambda (t) t::name) unfinished))
- (pids (map (lambda (t) t::pid) unfinished)))
+ (pids (map (lambda (t) t::pid) unfinished))
+ (any #f))
(for-each
(lambda (test retcode)
- (test::set-end-time!)
- (test:::set! 'retcode retcode))
+ (unless (< retcode 0)
+ (test::set-end-time!)
+ (test:::set! 'retcode retcode)
+ (test::report)
+ (sem::release!)
+ (set! any #t)))
(map pid->test pids)
- (wait-processes (map stringify names) pids #t)))))
+ (wait-processes (map stringify names) pids hang))
+
+ ;; If some processes finished, try to start new ones.
+ (let loop ()
+ (cond
+ ((not any) #f)
+ ((pair? enqueued)
+ (if (sem::acquire!?)
+ (let ((test (pop-test!)))
+ (add (test::run-async))
+ (loop)))))))))
(current-environment))
(define (filter-tests status)
(filter (lambda (p) (eq? status (p::status))) procs))
@@ -629,6 +708,10 @@
(define (set-end-time!)
(set! end-time (get-time)))
+ ;; Has the test been started yet?
+ (define (started?)
+ (number? pid))
+
(define (open-log-file)
(unless log-file-name
(set! log-file-name (string-append (basename name) ".log")))
@@ -713,23 +796,22 @@
;; Run the setup target to create an environment, then run all given
;; tests in parallel.
-(define (run-tests-parallel tests)
- (let loop ((pool (test-pool::new '())) (tests' tests))
+(define (run-tests-parallel tests n)
+ (let loop ((pool (test-pool::new n)) (tests' tests))
(if (null? tests')
(let ((results (pool::wait)))
- (for-each (lambda (t) (t::report)) (reverse results::procs))
((results::xml) (open-output-file "report.xml"))
(exit (results::report)))
(let ((wd (mkdtemp-autoremove))
(test (car tests')))
(test:::set! 'directory wd)
- (loop (pool::add (test::run-async))
+ (loop (pool::add test)
(cdr tests'))))))
;; Run the setup target to create an environment, then run all given
;; tests in sequence.
(define (run-tests-sequential tests)
- (let loop ((pool (test-pool::new '())) (tests' tests))
+ (let loop ((pool (test-pool::new 1)) (tests' tests))
(if (null? tests')
(let ((results (pool::wait)))
((results::xml) (open-output-file "report.xml"))
@@ -743,10 +825,14 @@
;; Run tests either in sequence or in parallel, depending on the
;; number of tests and the command line flags.
(define (run-tests tests)
- (if (and (flag "--parallel" *args*)
- (> (length tests) 1))
- (run-tests-parallel tests)
- (run-tests-sequential tests)))
+ (let ((parallel (flag "--parallel" *args*))
+ (default-parallel-jobs 32))
+ (if (and parallel (> (length tests) 1))
+ (run-tests-parallel tests (if (and (pair? parallel)
+ (string->number (car parallel)))
+ (string->number (car parallel))
+ default-parallel-jobs))
+ (run-tests-sequential tests))))
;; Load all tests from the given path.
(define (load-tests . path)
@@ -762,11 +848,14 @@
(let ((tarball (make-temporary-file "environment-cache")))
(atexit (lambda () (remove-temporary-file tarball)))
(setup::run-sync '--create-tarball tarball)
+ (if (not (equal? 'PASS (setup::status)))
+ (fail "Setup failed."))
`(--unpack-tarball ,tarball)))))
;; Command line flag handling. Returns the elements following KEY in
;; ARGUMENTS up to the next argument, or #f if KEY is not in
-;; ARGUMENTS.
+;; ARGUMENTS. If 'KEY=XYZ' is encountered, then the singleton list
+;; containing 'XYZ' is returned.
(define (flag key arguments)
(cond
((null? arguments)
@@ -777,6 +866,10 @@
(if (or (null? args) (string-prefix? (car args) "--"))
(reverse acc)
(loop (cons (car args) acc) (cdr args)))))
+ ((string-prefix? (car arguments) (string-append key "="))
+ (list (substring (car arguments)
+ (+ (string-length key) 1)
+ (string-length (car arguments)))))
((string=? "--" (car arguments))
#f)
(else
@@ -784,6 +877,7 @@
(assert (equal? (flag "--xxx" '("--yyy")) #f))
(assert (equal? (flag "--xxx" '("--xxx")) '()))
(assert (equal? (flag "--xxx" '("--xxx" "yyy")) '("yyy")))
+(assert (equal? (flag "--xxx" '("--xxx=foo" "yyy")) '("foo")))
(assert (equal? (flag "--xxx" '("--xxx" "yyy" "zzz")) '("yyy" "zzz")))
(assert (equal? (flag "--xxx" '("--xxx" "yyy" "zzz" "--")) '("yyy" "zzz")))
(assert (equal? (flag "--xxx" '("--xxx" "yyy" "--" "zzz")) '("yyy")))
diff --git a/tests/gpgsm/gpgsm-defs.scm b/tests/gpgsm/gpgsm-defs.scm
index 711922a..d99d7da 100644
--- a/tests/gpgsm/gpgsm-defs.scm
+++ b/tests/gpgsm/gpgsm-defs.scm
@@ -66,7 +66,9 @@
"disable-crl-checks"
"faked-system-time 1008241200")
(create-file "gpg-agent.conf"
- (string-append "pinentry-program " (tool 'pinentry)))
+ (string-append "pinentry-program " (tool 'pinentry))
+ (string-append "scdaemon-program " (tool 'scdaemon))
+ )
(start-agent)
(create-file
"trustlist.txt"
diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am
index bf9673f..506bce5 100644
--- a/tests/openpgp/Makefile.am
+++ b/tests/openpgp/Makefile.am
@@ -74,6 +74,7 @@ XTESTS = \
multisig.scm \
verify.scm \
verify-multifile.scm \
+ gpgv.scm \
gpgv-forged-keyring.scm \
armor.scm \
import.scm \
@@ -250,7 +251,7 @@ sample_msgs = samplemsgs/clearsig-1-key-1.asc \
EXTRA_DIST = defs.scm $(XTESTS) $(TEST_FILES) \
mkdemodirs signdemokey $(priv_keys) $(sample_keys) \
$(sample_msgs) ChangeLog-2011 run-tests.scm \
- setup.scm shell.scm all-tests.scm
+ setup.scm shell.scm all-tests.scm signed-messages.scm
CLEANFILES = prepared.stamp x y yy z out err $(data_files) \
plain-1 plain-2 plain-3 trustdb.gpg *.lock .\#lk* \
diff --git a/tests/openpgp/all-tests.scm b/tests/openpgp/all-tests.scm
index 6584df2..4dd6d6f 100644
--- a/tests/openpgp/all-tests.scm
+++ b/tests/openpgp/all-tests.scm
@@ -33,13 +33,19 @@
(path-join "tests" "openpgp" "setup.scm")
(in-srcdir "tests" "openpgp" "setup.scm"))))
- (define setup-use-keyring
+ (define (qualify path variant)
+ (string-append "<" variant ">" path))
+
+ (define (setup* variant)
(make-environment-cache
(test::scm
#f
- (string-append "<use-keyring>" (path-join "tests" "openpgp" "setup.scm"))
+ (qualify (path-join "tests" "openpgp" "setup.scm") variant)
(in-srcdir "tests" "openpgp" "setup.scm")
- "--use-keyring")))
+ (string-append "--" variant))))
+
+ (define setup-use-keyring (setup* "use-keyring"))
+ (define setup-extended-key-format (setup* "extended-key-format"))
(define all-tests
(parse-makefile-expand (in-srcdir "tests" "openpgp" "Makefile.am")
@@ -52,7 +58,11 @@
(in-srcdir "tests" "openpgp" name))) all-tests)
(map (lambda (name)
(test::scm setup-use-keyring
- (string-append "<use-keyring>"
- (path-join "tests" "openpgp" name))
+ (qualify (path-join "tests" "openpgp" name) "use-keyring")
+ (in-srcdir "tests" "openpgp" name)
+ "--use-keyring")) all-tests)
+ (map (lambda (name)
+ (test::scm setup-extended-key-format
+ (qualify (path-join "tests" "openpgp" name) "extended-key-format")
(in-srcdir "tests" "openpgp" name)
- "--use-keyring")) all-tests)))
+ "--extended-key-format")) all-tests)))
diff --git a/tests/openpgp/defs.scm b/tests/openpgp/defs.scm
index 1531dc1..b5e3078 100644
--- a/tests/openpgp/defs.scm
+++ b/tests/openpgp/defs.scm
@@ -316,6 +316,7 @@
(display (make-random-string size) port))))
(define (create-file name . lines)
+ (catch #f (unlink name))
(letfd ((fd (open name (logior O_WRONLY O_CREAT O_BINARY) #o600)))
(let ((port (fdopen fd "wb")))
(for-each (lambda (line) (display line port) (newline port))
@@ -348,7 +349,10 @@
"allow-preset-passphrase"
"no-grab"
"enable-ssh-support"
+ (if (flag "--extended-key-format" *args*)
+ "enable-extended-key-format" "#enable-extended-key-format")
(string-append "pinentry-program " (tool 'pinentry))
+ (string-append "scdaemon-program " (tool 'scdaemon))
))
;; Initialize the test environment, install appropriate configuration
@@ -447,7 +451,7 @@
(with-home-directory gnupghome
(stop-agent)))))
(catch (log "Warning: Creating socket directory failed:" (car *error*))
- (call-popen `(,(tool 'gpgconf) --create-socketdir) ""))
+ (gpg-conf '--create-socketdir))
(call-check `(,(tool 'gpg-connect-agent) --verbose
,(string-append "--agent-program=" (tool 'gpg-agent)
"|--debug-quick-random")
@@ -456,9 +460,9 @@
;; Stop the agent and other daemons and remove the socket dir.
(define (stop-agent)
(log "Stopping gpg-agent...")
- (call-check `(,(tool 'gpgconf) --kill all))
+ (gpg-conf '--kill 'all)
(catch (log "Warning: Removing socket directory failed.")
- (call-popen `(,(tool 'gpgconf) --remove-socketdir) "")))
+ (gpg-conf '--remove-socketdir)))
;; end
diff --git a/tests/openpgp/gpgv.scm b/tests/openpgp/gpgv.scm
new file mode 100755
index 0000000..819d15f
--- /dev/null
+++ b/tests/openpgp/gpgv.scm
@@ -0,0 +1,75 @@
+#!/usr/bin/env gpgscm
+
+;; Copyright (C) 2016-2017 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/>.
+
+(load (in-srcdir "tests" "openpgp" "defs.scm"))
+(load (in-srcdir "tests" "openpgp" "signed-messages.scm"))
+(setup-legacy-environment)
+
+(define keyring (if (file-exists? "pubring.kbx") "pubring.kbx" "pubring.gpg"))
+
+;;
+;; Two simple tests to check that verify fails for bad input data
+;;
+(for-each-p
+ "Checking bogus signature"
+ (lambda (char)
+ (lettmp (x)
+ (call-with-binary-output-file
+ x
+ (lambda (port)
+ (display (make-string 64 (integer->char (string->number char)))
+ port)))
+ (if (= 0 (call `(,@gpgv --keyring ,keyring ,x data-500)))
+ (fail "no error code from verify"))))
+ '("#x2d" "#xca"))
+
+;; Fixme: We need more tests with manipulated cleartext signatures.
+
+;;
+;; Now run the tests.
+;;
+(for-each-p
+ "Checking that a valid signature is verified as such"
+ (lambda (armored-file)
+ (pipe:do
+ (pipe:echo (eval armored-file (current-environment)))
+ (pipe:spawn `(,@gpgv --keyring ,keyring))))
+ '(msg_ols_asc msg_cols_asc msg_sl_asc msg_oolss_asc msg_cls_asc msg_clss_asc))
+
+(for-each-p
+ "Checking that an invalid signature is verified as such"
+ (lambda (armored-file)
+ (catch '()
+ (pipe:do
+ (pipe:echo (eval armored-file (current-environment)))
+ (pipe:spawn `(,@gpgv --keyring ,keyring)))
+ (fail "verification succeeded but should not")))
+ '(bad_ls_asc bad_fols_asc bad_olsf_asc bad_ools_asc))
+
+
+;; Need to import the ed25519 sample key used for the next two tests.
+(call-check `(,@gpg --quiet --yes
+ --import ,(in-srcdir "tests" "openpgp" key-file2)))
+(for-each-p
+ "Checking that a valid Ed25519 signature is verified as such"
+ (lambda (armored-file)
+ (pipe:do
+ (pipe:echo (eval armored-file (current-environment)))
+ (pipe:spawn `(,@gpgv --keyring ,keyring))))
+ '(msg_ed25519_rshort msg_ed25519_sshort))
diff --git a/tests/openpgp/shell.scm b/tests/openpgp/shell.scm
index bd6059a..347b3a0 100644
--- a/tests/openpgp/shell.scm
+++ b/tests/openpgp/shell.scm
@@ -18,7 +18,6 @@
;; along with this program; if not, see <http://www.gnu.org/licenses/>.
(load (in-srcdir "tests" "openpgp" "defs.scm"))
-(setup-environment)
;; This is not a test, but can be used to inspect the test
;; environment. Simply execute
@@ -27,7 +26,28 @@
;;
;; to run it.
-(echo "Note that gpg.conf includes 'batch'. If you want to use gpg")
-(echo "interactively you should drop that.")
-(echo)
+(if (prompt-yes-no? "Load legacy test environment" #t)
+ (setup-legacy-environment)
+ (setup-environment))
+
+(if (prompt-yes-no? "Drop 'batch' from gpg.conf" #t)
+ (apply create-file
+ (cons "gpg.conf"
+ (filter (lambda (line) (not (equal? "batch" line)))
+ (string-split-newlines
+ (call-with-input-file "gpg.conf" read-all)))))
+ (begin
+ (echo "Note that gpg.conf includes 'batch'. If you want to use gpg")
+ (echo "interactively you should drop that.")))
+
+;; Add paths to tools to PATH.
+(setenv "PATH" (pathsep-join
+ (append (map (lambda (t) (dirname (tool t)))
+ '(gpg gpg-agent scdaemon gpgsm dirmngr gpgconf))
+ (pathsep-split (getenv "PATH"))))
+ #t)
+
+(echo "\nEnjoy your test environment. "
+ "Type 'exit' to exit it, it will be cleaned up after you.\n")
+
(interactive-shell)
diff --git a/tests/openpgp/signed-messages.scm b/tests/openpgp/signed-messages.scm
new file mode 100644
index 0000000..d012f2f
--- /dev/null
+++ b/tests/openpgp/signed-messages.scm
@@ -0,0 +1,281 @@
+;; Copyright (C) 2016 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/>.
+
+;; A plain signed message created using
+;; echo abc | gpg --homedir . --passphrase-fd 0 -u Alpha -z0 -sa msg
+(define msg_ols_asc "
+-----BEGIN PGP MESSAGE-----
+
+kA0DAAIRLXJ8x2hpdzQBrQEHYgNtc2dEDFJaSSB0aGluayB0aGF0IGFsbCByaWdo
+dC10aGlua2luZyBwZW9wbGUgaW4gdGhpcyBjb3VudHJ5IGFyZSBzaWNrIGFuZAp0
+aXJlZCBvZiBiZWluZyB0b2xkIHRoYXQgb3JkaW5hcnkgZGVjZW50IHBlb3BsZSBh
+cmUgZmVkIHVwIGluIHRoaXMKY291bnRyeSB3aXRoIGJlaW5nIHNpY2sgYW5kIHRp
+cmVkLiAgSSdtIGNlcnRhaW5seSBub3QuICBCdXQgSSdtCnNpY2sgYW5kIHRpcmVk
+IG9mIGJlaW5nIHRvbGQgdGhhdCBJIGFtLgotIE1vbnR5IFB5dGhvbgqIPwMFAEQM
+UlotcnzHaGl3NBECR4IAoJlEGTY+bHjD2HYuCixLQCmk01pbAKCIjkzLOAmkZNm0
+D8luT78c/1x45Q==
+=a29i
+-----END PGP MESSAGE-----
+")
+
+;; A plain signed message created using
+;; echo abc | gpg --homedir . --passphrase-fd 0 -u Alpha -sa msg
+(define msg_cols_asc "
+-----BEGIN PGP MESSAGE-----
+
+owGbwMvMwCSoW1RzPCOz3IRxLSN7EnNucboLT6Cgp0JJRmZeNpBMLFFIzMlRKMpM
+zyjRBQtm5qUrFKTmF+SkKmTmgdQVKyTnl+aVFFUqJBalKhRnJmcrJOalcJVkFqWm
+KOSnKSSlgrSU5OekQMzLL0rJzEsEKk9JTU7NK4EZBtKcBtRRWgAzlwtmbnlmSQbU
+GJjxCmDj9RQUPNVzFZJTi0oSM/NyKhXy8kuAYk6lJSBxLlTF2NziqZCYq8elq+Cb
+n1dSqRBQWZKRn8fVYc/MygAKBljYCDIFiTDMT+9seu836Q+bevyHTJ0dzPNuvCjn
+ZpgrwX38z58rJsfYDhwOSS4SkN/d6vUAAA==
+=s6sY
+-----END PGP MESSAGE-----
+")
+
+;; A PGP 2 style message.
+(define msg_sl_asc "
+-----BEGIN PGP MESSAGE-----
+
+iD8DBQBEDFJaLXJ8x2hpdzQRAkeCAKCZRBk2Pmx4w9h2LgosS0AppNNaWwCgiI5M
+yzgJpGTZtA/Jbk+/HP9ceOWtAQdiA21zZ0QMUlpJIHRoaW5rIHRoYXQgYWxsIHJp
+Z2h0LXRoaW5raW5nIHBlb3BsZSBpbiB0aGlzIGNvdW50cnkgYXJlIHNpY2sgYW5k
+CnRpcmVkIG9mIGJlaW5nIHRvbGQgdGhhdCBvcmRpbmFyeSBkZWNlbnQgcGVvcGxl
+IGFyZSBmZWQgdXAgaW4gdGhpcwpjb3VudHJ5IHdpdGggYmVpbmcgc2ljayBhbmQg
+dGlyZWQuICBJJ20gY2VydGFpbmx5IG5vdC4gIEJ1dCBJJ20Kc2ljayBhbmQgdGly
+ZWQgb2YgYmVpbmcgdG9sZCB0aGF0IEkgYW0uCi0gTW9udHkgUHl0aG9uCg==
+=0ukK
+-----END PGP MESSAGE-----
+")
+
+;; An OpenPGP message lacking the onepass packet. We used to accept
+;; such messages but now consider them invalid.
+(define bad_ls_asc "
+-----BEGIN PGP MESSAGE-----
+
+rQEHYgNtc2dEDFJaSSB0aGluayB0aGF0IGFsbCByaWdodC10aGlua2luZyBwZW9w
+bGUgaW4gdGhpcyBjb3VudHJ5IGFyZSBzaWNrIGFuZAp0aXJlZCBvZiBiZWluZyB0
+b2xkIHRoYXQgb3JkaW5hcnkgZGVjZW50IHBlb3BsZSBhcmUgZmVkIHVwIGluIHRo
+aXMKY291bnRyeSB3aXRoIGJlaW5nIHNpY2sgYW5kIHRpcmVkLiAgSSdtIGNlcnRh
+aW5seSBub3QuICBCdXQgSSdtCnNpY2sgYW5kIHRpcmVkIG9mIGJlaW5nIHRvbGQg
+dGhhdCBJIGFtLgotIE1vbnR5IFB5dGhvbgqIPwMFAEQMUlotcnzHaGl3NBECR4IA
+oJlEGTY+bHjD2HYuCixLQCmk01pbAKCIjkzLOAmkZNm0D8luT78c/1x45Q==
+=Mpiu
+-----END PGP MESSAGE-----
+")
+
+
+;; A signed message prefixed with an unsigned literal packet.
+;; (fols = faked-literal-data, one-pass, literal-data, signature)
+;; This should throw an error because running gpg to extract the
+;; signed data will return both literal data packets
+(define bad_fols_asc "
+-----BEGIN PGP MESSAGE-----
+
+rF1iDG1zZy51bnNpZ25lZEQMY0x0aW1lc2hhcmluZywgbjoKCUFuIGFjY2VzcyBt
+ZXRob2Qgd2hlcmVieSBvbmUgY29tcHV0ZXIgYWJ1c2VzIG1hbnkgcGVvcGxlLgqQ
+DQMAAhEtcnzHaGl3NAGtAQdiA21zZ0QMUlpJIHRoaW5rIHRoYXQgYWxsIHJpZ2h0
+LXRoaW5raW5nIHBlb3BsZSBpbiB0aGlzIGNvdW50cnkgYXJlIHNpY2sgYW5kCnRp
+cmVkIG9mIGJlaW5nIHRvbGQgdGhhdCBvcmRpbmFyeSBkZWNlbnQgcGVvcGxlIGFy
+ZSBmZWQgdXAgaW4gdGhpcwpjb3VudHJ5IHdpdGggYmVpbmcgc2ljayBhbmQgdGly
+ZWQuICBJJ20gY2VydGFpbmx5IG5vdC4gIEJ1dCBJJ20Kc2ljayBhbmQgdGlyZWQg
+b2YgYmVpbmcgdG9sZCB0aGF0IEkgYW0uCi0gTW9udHkgUHl0aG9uCog/AwUARAxS
+Wi1yfMdoaXc0EQJHggCgmUQZNj5seMPYdi4KLEtAKaTTWlsAoIiOTMs4CaRk2bQP
+yW5Pvxz/XHjl
+=UNM4
+-----END PGP MESSAGE-----
+")
+
+;; A signed message suffixed with an unsigned literal packet.
+;; (fols = faked-literal-data, one-pass, literal-data, signature)
+;; This should throw an error because running gpg to extract the
+;; signed data will return both literal data packets
+(define bad_olsf_asc "
+-----BEGIN PGP MESSAGE-----
+
+kA0DAAIRLXJ8x2hpdzQBrQEHYgNtc2dEDFJaSSB0aGluayB0aGF0IGFsbCByaWdo
+dC10aGlua2luZyBwZW9wbGUgaW4gdGhpcyBjb3VudHJ5IGFyZSBzaWNrIGFuZAp0
+aXJlZCBvZiBiZWluZyB0b2xkIHRoYXQgb3JkaW5hcnkgZGVjZW50IHBlb3BsZSBh
+cmUgZmVkIHVwIGluIHRoaXMKY291bnRyeSB3aXRoIGJlaW5nIHNpY2sgYW5kIHRp
+cmVkLiAgSSdtIGNlcnRhaW5seSBub3QuICBCdXQgSSdtCnNpY2sgYW5kIHRpcmVk
+IG9mIGJlaW5nIHRvbGQgdGhhdCBJIGFtLgotIE1vbnR5IFB5dGhvbgqIPwMFAEQM
+UlotcnzHaGl3NBECR4IAoJlEGTY+bHjD2HYuCixLQCmk01pbAKCIjkzLOAmkZNm0
+D8luT78c/1x45axdYgxtc2cudW5zaWduZWREDGNMdGltZXNoYXJpbmcsIG46CglB
+biBhY2Nlc3MgbWV0aG9kIHdoZXJlYnkgb25lIGNvbXB1dGVyIGFidXNlcyBtYW55
+IHBlb3BsZS4K
+=3gnG
+-----END PGP MESSAGE-----
+")
+
+
+;; Two standard signed messages in a row
+(define msg_olsols_asc_multiple "
+-----BEGIN PGP MESSAGE-----
+
+kA0DAAIRLXJ8x2hpdzQBrQEHYgNtc2dEDFJaSSB0aGluayB0aGF0IGFsbCByaWdo
+dC10aGlua2luZyBwZW9wbGUgaW4gdGhpcyBjb3VudHJ5IGFyZSBzaWNrIGFuZAp0
+aXJlZCBvZiBiZWluZyB0b2xkIHRoYXQgb3JkaW5hcnkgZGVjZW50IHBlb3BsZSBh
+cmUgZmVkIHVwIGluIHRoaXMKY291bnRyeSB3aXRoIGJlaW5nIHNpY2sgYW5kIHRp
+cmVkLiAgSSdtIGNlcnRhaW5seSBub3QuICBCdXQgSSdtCnNpY2sgYW5kIHRpcmVk
+IG9mIGJlaW5nIHRvbGQgdGhhdCBJIGFtLgotIE1vbnR5IFB5dGhvbgqIPwMFAEQM
+UlotcnzHaGl3NBECR4IAoJlEGTY+bHjD2HYuCixLQCmk01pbAKCIjkzLOAmkZNm0
+D8luT78c/1x45ZANAwACES1yfMdoaXc0Aa0BB2IDbXNnRAxSWkkgdGhpbmsgdGhh
+dCBhbGwgcmlnaHQtdGhpbmtpbmcgcGVvcGxlIGluIHRoaXMgY291bnRyeSBhcmUg
+c2ljayBhbmQKdGlyZWQgb2YgYmVpbmcgdG9sZCB0aGF0IG9yZGluYXJ5IGRlY2Vu
+dCBwZW9wbGUgYXJlIGZlZCB1cCBpbiB0aGlzCmNvdW50cnkgd2l0aCBiZWluZyBz
+aWNrIGFuZCB0aXJlZC4gIEknbSBjZXJ0YWlubHkgbm90LiAgQnV0IEknbQpzaWNr
+IGFuZCB0aXJlZCBvZiBiZWluZyB0b2xkIHRoYXQgSSBhbS4KLSBNb250eSBQeXRo
+b24KiD8DBQBEDFJaLXJ8x2hpdzQRAkeCAKCZRBk2Pmx4w9h2LgosS0AppNNaWwCg
+iI5MyzgJpGTZtA/Jbk+/HP9ceOU=
+=8nLN
+-----END PGP MESSAGE-----
+")
+
+;; A standard message with two signatures (actually the same signature
+;; duplicated).
+(define msg_oolss_asc "
+-----BEGIN PGP MESSAGE-----
+
+kA0DAAIRLXJ8x2hpdzQBkA0DAAIRLXJ8x2hpdzQBrQEHYgNtc2dEDFJaSSB0aGlu
+ayB0aGF0IGFsbCByaWdodC10aGlua2luZyBwZW9wbGUgaW4gdGhpcyBjb3VudHJ5
+IGFyZSBzaWNrIGFuZAp0aXJlZCBvZiBiZWluZyB0b2xkIHRoYXQgb3JkaW5hcnkg
+ZGVjZW50IHBlb3BsZSBhcmUgZmVkIHVwIGluIHRoaXMKY291bnRyeSB3aXRoIGJl
+aW5nIHNpY2sgYW5kIHRpcmVkLiAgSSdtIGNlcnRhaW5seSBub3QuICBCdXQgSSdt
+CnNpY2sgYW5kIHRpcmVkIG9mIGJlaW5nIHRvbGQgdGhhdCBJIGFtLgotIE1vbnR5
+IFB5dGhvbgqIPwMFAEQMUlotcnzHaGl3NBECR4IAoJlEGTY+bHjD2HYuCixLQCmk
+01pbAKCIjkzLOAmkZNm0D8luT78c/1x45Yg/AwUARAxSWi1yfMdoaXc0EQJHggCg
+mUQZNj5seMPYdi4KLEtAKaTTWlsAoIiOTMs4CaRk2bQPyW5Pvxz/XHjl
+=KVw5
+-----END PGP MESSAGE-----
+")
+
+;; A standard message with two one-pass packet but only one signature
+;; packet
+(define bad_ools_asc "
+-----BEGIN PGP MESSAGE-----
+
+kA0DAAIRLXJ8x2hpdzQBkA0DAAIRLXJ8x2hpdzQBrQEHYgNtc2dEDFJaSSB0aGlu
+ayB0aGF0IGFsbCByaWdodC10aGlua2luZyBwZW9wbGUgaW4gdGhpcyBjb3VudHJ5
+IGFyZSBzaWNrIGFuZAp0aXJlZCBvZiBiZWluZyB0b2xkIHRoYXQgb3JkaW5hcnkg
+ZGVjZW50IHBlb3BsZSBhcmUgZmVkIHVwIGluIHRoaXMKY291bnRyeSB3aXRoIGJl
+aW5nIHNpY2sgYW5kIHRpcmVkLiAgSSdtIGNlcnRhaW5seSBub3QuICBCdXQgSSdt
+CnNpY2sgYW5kIHRpcmVkIG9mIGJlaW5nIHRvbGQgdGhhdCBJIGFtLgotIE1vbnR5
+IFB5dGhvbgqIPwMFAEQMUlotcnzHaGl3NBECR4IAoJlEGTY+bHjD2HYuCixLQCmk
+01pbAKCIjkzLOAmkZNm0D8luT78c/1x45Q==
+=1/ix
+-----END PGP MESSAGE-----
+")
+
+;; Standard cleartext signature
+(define msg_cls_asc "
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+I think that all right-thinking people in this country are sick and
+tired of being told that ordinary decent people are fed up in this
+country with being sick and tired. I'm certainly not. But I'm
+sick and tired of being told that I am.
+- - Monty Python
+-----BEGIN PGP SIGNATURE-----
+
+iD8DBQFEDVp1LXJ8x2hpdzQRAplUAKCMfpG3GPw/TLN52tosgXP5lNECkwCfQhAa
+emmev7IuQjWYrGF9Lxj+zj8=
+=qJsY
+-----END PGP SIGNATURE-----
+")
+
+;; Cleartext signature with two signatures
+(define msg_clss_asc "
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+What is the difference between a Turing machine and the modern computer?
+It's the same as that between Hillary's ascent of Everest and the
+establishment of a Hilton on its peak.
+-----BEGIN PGP SIGNATURE-----
+
+iD8DBQFEDVz6LXJ8x2hpdzQRAtkGAKCeMhNbHnh339fpjNj9owsYcC4zBwCfYO5l
+2u+KEfXX0FKyk8SMzLjZ536IPwMFAUQNXPr+GAsdqeOwshEC2QYAoPOWAiQm0EF/
+FWIAQUplk7JWbyRKAJ92ZJyJpWfzb0yc1s7MY65r2qEHrg==
+=1Xvv
+-----END PGP SIGNATURE-----
+")
+
+;; Two clear text signatures in a row
+(define msg_clsclss_asc_multiple (string-append msg_cls_asc msg_clss_asc))
+
+
+;; An Ed25519 cleartext message with an R parameter of only 247 bits
+;; so that the code to re-insert the stripped zero byte kicks in. The
+;; S parameter has 253 bits but that does not strip a full byte.
+;;
+;; Note that the message has a typo ("the the"), but this should not
+;; be fixed because it breaks this test.
+(define msg_ed25519_rshort "
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA256
+
+Dear Emily:
+ I'm still confused as to what groups articles should be posted
+to. How about an example?
+ -- Still Confused
+
+Dear Still:
+ Ok. Let's say you want to report that Gretzky has been traded from
+the Oilers to the Kings. Now right away you might think rec.sport.hockey
+would be enough. WRONG. Many more people might be interested. This is a
+big trade! Since it's a NEWS article, it belongs in the news.* hierarchy
+as well. If you are a news admin, or there is one on your machine, try
+news.admin. If not, use news.misc.
+ The Oilers are probably interested in geology, so try sci.physics.
+He is a big star, so post to sci.astro, and sci.space because they are also
+interested in stars. Next, his name is Polish sounding. So post to
+soc.culture.polish. But that group doesn't exist, so cross-post to
+news.groups suggesting it should be created. With this many groups of
+interest, your article will be quite bizarre, so post to talk.bizarre as
+well. (And post to comp.std.mumps, since they hardly get any articles
+there, and a \"comp\" group will propagate your article further.)
+ You may also find it is more fun to post the article once in each
+group. If you list all the newsgroups in the same article, some newsreaders
+will only show the the article to the reader once! Don't tolerate this.
+ -- Emily Postnews Answers Your Questions on Netiquette
+-----BEGIN PGP SIGNATURE-----
+
+iJEEARYIADoWIQSyHeq0+HX7PaQvHR0TlWNoKgINCgUCV772DhwccGF0cmljZS5s
+dW11bWJhQGV4YW1wbGUubmV0AAoJEBOVY2gqAg0KMAIA90EtUwAja0iJGpO91wyz
+GLh9pS5v495V0r94yU6uUyUA/RT/StyPWe1wbnEZuacZnLbUV6Yy/aTXCVAlxf0r
+TusO
+=vQ3f
+-----END PGP SIGNATURE-----
+")
+
+;; An Ed25519 cleartext message with an S parameter of only 248 bits
+;; so that the code to re-insert the stripped zero byte kicks in.
+(define msg_ed25519_sshort "
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA256
+
+All articles that coruscate with resplendence are not truly auriferous.
+-----BEGIN PGP SIGNATURE-----
+
+iJEEARYIADoWIQSyHeq0+HX7PaQvHR0TlWNoKgINCgUCV771QhwccGF0cmljZS5s
+dW11bWJhQGV4YW1wbGUubmV0AAoJEBOVY2gqAg0KHVEBAI66OPDYXKWO3r6SaFT+
+uxmh8x4ZerW41vMA9gkJ4AEKAPjoe/Z7fDqo1lCptIFutFAGbfNxcm/53prfx2fT
+GisM
+=L7sk
+-----END PGP SIGNATURE-----
+")
diff --git a/tests/openpgp/ssh-export.scm b/tests/openpgp/ssh-export.scm
index 7f51447..136c6e0 100755
--- a/tests/openpgp/ssh-export.scm
+++ b/tests/openpgp/ssh-export.scm
@@ -44,8 +44,8 @@
(call-check `(,@GPG --yes --import ,(:file key)))
(let* ((result (call-check `(,@GPG --export-ssh-key ,(:fpr key))))
- ;; XXX: We should split at any whitespace here.
- (parts (string-split (string-trim char-whitespace? result) #\space)))
+ (parts (string-splitp (string-trim char-whitespace? result)
+ char-whitespace? -1)))
(assert (string=? (car parts) (:kind key)))
;; XXX: We should not use a short keyid as the comment when
;; exporting an ssh key.
diff --git a/tests/openpgp/verify.scm b/tests/openpgp/verify.scm
index cb6eb59..b4dd49b 100755
--- a/tests/openpgp/verify.scm
+++ b/tests/openpgp/verify.scm
@@ -18,6 +18,7 @@
;; along with this program; if not, see <http://www.gnu.org/licenses/>.
(load (in-srcdir "tests" "openpgp" "defs.scm"))
+(load (in-srcdir "tests" "openpgp" "signed-messages.scm"))
(setup-legacy-environment)
;;
@@ -36,273 +37,6 @@
(fail "no error code from verify"))))
'("#x2d" "#xca"))
-;; A plain signed message created using
-;; echo abc | gpg --homedir . --passphrase-fd 0 -u Alpha -z0 -sa msg
-(define msg_ols_asc "
------BEGIN PGP MESSAGE-----
-
-kA0DAAIRLXJ8x2hpdzQBrQEHYgNtc2dEDFJaSSB0aGluayB0aGF0IGFsbCByaWdo
-dC10aGlua2luZyBwZW9wbGUgaW4gdGhpcyBjb3VudHJ5IGFyZSBzaWNrIGFuZAp0
-aXJlZCBvZiBiZWluZyB0b2xkIHRoYXQgb3JkaW5hcnkgZGVjZW50IHBlb3BsZSBh
-cmUgZmVkIHVwIGluIHRoaXMKY291bnRyeSB3aXRoIGJlaW5nIHNpY2sgYW5kIHRp
-cmVkLiAgSSdtIGNlcnRhaW5seSBub3QuICBCdXQgSSdtCnNpY2sgYW5kIHRpcmVk
-IG9mIGJlaW5nIHRvbGQgdGhhdCBJIGFtLgotIE1vbnR5IFB5dGhvbgqIPwMFAEQM
-UlotcnzHaGl3NBECR4IAoJlEGTY+bHjD2HYuCixLQCmk01pbAKCIjkzLOAmkZNm0
-D8luT78c/1x45Q==
-=a29i
------END PGP MESSAGE-----
-")
-
-;; A plain signed message created using
-;; echo abc | gpg --homedir . --passphrase-fd 0 -u Alpha -sa msg
-(define msg_cols_asc "
------BEGIN PGP MESSAGE-----
-
-owGbwMvMwCSoW1RzPCOz3IRxLSN7EnNucboLT6Cgp0JJRmZeNpBMLFFIzMlRKMpM
-zyjRBQtm5qUrFKTmF+SkKmTmgdQVKyTnl+aVFFUqJBalKhRnJmcrJOalcJVkFqWm
-KOSnKSSlgrSU5OekQMzLL0rJzEsEKk9JTU7NK4EZBtKcBtRRWgAzlwtmbnlmSQbU
-GJjxCmDj9RQUPNVzFZJTi0oSM/NyKhXy8kuAYk6lJSBxLlTF2NziqZCYq8elq+Cb
-n1dSqRBQWZKRn8fVYc/MygAKBljYCDIFiTDMT+9seu836Q+bevyHTJ0dzPNuvCjn
-ZpgrwX38z58rJsfYDhwOSS4SkN/d6vUAAA==
-=s6sY
------END PGP MESSAGE-----
-")
-
-;; A PGP 2 style message.
-(define msg_sl_asc "
------BEGIN PGP MESSAGE-----
-
-iD8DBQBEDFJaLXJ8x2hpdzQRAkeCAKCZRBk2Pmx4w9h2LgosS0AppNNaWwCgiI5M
-yzgJpGTZtA/Jbk+/HP9ceOWtAQdiA21zZ0QMUlpJIHRoaW5rIHRoYXQgYWxsIHJp
-Z2h0LXRoaW5raW5nIHBlb3BsZSBpbiB0aGlzIGNvdW50cnkgYXJlIHNpY2sgYW5k
-CnRpcmVkIG9mIGJlaW5nIHRvbGQgdGhhdCBvcmRpbmFyeSBkZWNlbnQgcGVvcGxl
-IGFyZSBmZWQgdXAgaW4gdGhpcwpjb3VudHJ5IHdpdGggYmVpbmcgc2ljayBhbmQg
-dGlyZWQuICBJJ20gY2VydGFpbmx5IG5vdC4gIEJ1dCBJJ20Kc2ljayBhbmQgdGly
-ZWQgb2YgYmVpbmcgdG9sZCB0aGF0IEkgYW0uCi0gTW9udHkgUHl0aG9uCg==
-=0ukK
------END PGP MESSAGE-----
-")
-
-;; An OpenPGP message lacking the onepass packet. We used to accept
-;; such messages but now consider them invalid.
-(define bad_ls_asc "
------BEGIN PGP MESSAGE-----
-
-rQEHYgNtc2dEDFJaSSB0aGluayB0aGF0IGFsbCByaWdodC10aGlua2luZyBwZW9w
-bGUgaW4gdGhpcyBjb3VudHJ5IGFyZSBzaWNrIGFuZAp0aXJlZCBvZiBiZWluZyB0
-b2xkIHRoYXQgb3JkaW5hcnkgZGVjZW50IHBlb3BsZSBhcmUgZmVkIHVwIGluIHRo
-aXMKY291bnRyeSB3aXRoIGJlaW5nIHNpY2sgYW5kIHRpcmVkLiAgSSdtIGNlcnRh
-aW5seSBub3QuICBCdXQgSSdtCnNpY2sgYW5kIHRpcmVkIG9mIGJlaW5nIHRvbGQg
-dGhhdCBJIGFtLgotIE1vbnR5IFB5dGhvbgqIPwMFAEQMUlotcnzHaGl3NBECR4IA
-oJlEGTY+bHjD2HYuCixLQCmk01pbAKCIjkzLOAmkZNm0D8luT78c/1x45Q==
-=Mpiu
------END PGP MESSAGE-----
-")
-
-
-;; A signed message prefixed with an unsigned literal packet.
-;; (fols = faked-literal-data, one-pass, literal-data, signature)
-;; This should throw an error because running gpg to extract the
-;; signed data will return both literal data packets
-(define bad_fols_asc "
------BEGIN PGP MESSAGE-----
-
-rF1iDG1zZy51bnNpZ25lZEQMY0x0aW1lc2hhcmluZywgbjoKCUFuIGFjY2VzcyBt
-ZXRob2Qgd2hlcmVieSBvbmUgY29tcHV0ZXIgYWJ1c2VzIG1hbnkgcGVvcGxlLgqQ
-DQMAAhEtcnzHaGl3NAGtAQdiA21zZ0QMUlpJIHRoaW5rIHRoYXQgYWxsIHJpZ2h0
-LXRoaW5raW5nIHBlb3BsZSBpbiB0aGlzIGNvdW50cnkgYXJlIHNpY2sgYW5kCnRp
-cmVkIG9mIGJlaW5nIHRvbGQgdGhhdCBvcmRpbmFyeSBkZWNlbnQgcGVvcGxlIGFy
-ZSBmZWQgdXAgaW4gdGhpcwpjb3VudHJ5IHdpdGggYmVpbmcgc2ljayBhbmQgdGly
-ZWQuICBJJ20gY2VydGFpbmx5IG5vdC4gIEJ1dCBJJ20Kc2ljayBhbmQgdGlyZWQg
-b2YgYmVpbmcgdG9sZCB0aGF0IEkgYW0uCi0gTW9udHkgUHl0aG9uCog/AwUARAxS
-Wi1yfMdoaXc0EQJHggCgmUQZNj5seMPYdi4KLEtAKaTTWlsAoIiOTMs4CaRk2bQP
-yW5Pvxz/XHjl
-=UNM4
------END PGP MESSAGE-----
-")
-
-;; A signed message suffixed with an unsigned literal packet.
-;; (fols = faked-literal-data, one-pass, literal-data, signature)
-;; This should throw an error because running gpg to extract the
-;; signed data will return both literal data packets
-(define bad_olsf_asc "
------BEGIN PGP MESSAGE-----
-
-kA0DAAIRLXJ8x2hpdzQBrQEHYgNtc2dEDFJaSSB0aGluayB0aGF0IGFsbCByaWdo
-dC10aGlua2luZyBwZW9wbGUgaW4gdGhpcyBjb3VudHJ5IGFyZSBzaWNrIGFuZAp0
-aXJlZCBvZiBiZWluZyB0b2xkIHRoYXQgb3JkaW5hcnkgZGVjZW50IHBlb3BsZSBh
-cmUgZmVkIHVwIGluIHRoaXMKY291bnRyeSB3aXRoIGJlaW5nIHNpY2sgYW5kIHRp
-cmVkLiAgSSdtIGNlcnRhaW5seSBub3QuICBCdXQgSSdtCnNpY2sgYW5kIHRpcmVk
-IG9mIGJlaW5nIHRvbGQgdGhhdCBJIGFtLgotIE1vbnR5IFB5dGhvbgqIPwMFAEQM
-UlotcnzHaGl3NBECR4IAoJlEGTY+bHjD2HYuCixLQCmk01pbAKCIjkzLOAmkZNm0
-D8luT78c/1x45axdYgxtc2cudW5zaWduZWREDGNMdGltZXNoYXJpbmcsIG46CglB
-biBhY2Nlc3MgbWV0aG9kIHdoZXJlYnkgb25lIGNvbXB1dGVyIGFidXNlcyBtYW55
-IHBlb3BsZS4K
-=3gnG
------END PGP MESSAGE-----
-")
-
-
-;; Two standard signed messages in a row
-(define msg_olsols_asc_multiple "
------BEGIN PGP MESSAGE-----
-
-kA0DAAIRLXJ8x2hpdzQBrQEHYgNtc2dEDFJaSSB0aGluayB0aGF0IGFsbCByaWdo
-dC10aGlua2luZyBwZW9wbGUgaW4gdGhpcyBjb3VudHJ5IGFyZSBzaWNrIGFuZAp0
-aXJlZCBvZiBiZWluZyB0b2xkIHRoYXQgb3JkaW5hcnkgZGVjZW50IHBlb3BsZSBh
-cmUgZmVkIHVwIGluIHRoaXMKY291bnRyeSB3aXRoIGJlaW5nIHNpY2sgYW5kIHRp
-cmVkLiAgSSdtIGNlcnRhaW5seSBub3QuICBCdXQgSSdtCnNpY2sgYW5kIHRpcmVk
-IG9mIGJlaW5nIHRvbGQgdGhhdCBJIGFtLgotIE1vbnR5IFB5dGhvbgqIPwMFAEQM
-UlotcnzHaGl3NBECR4IAoJlEGTY+bHjD2HYuCixLQCmk01pbAKCIjkzLOAmkZNm0
-D8luT78c/1x45ZANAwACES1yfMdoaXc0Aa0BB2IDbXNnRAxSWkkgdGhpbmsgdGhh
-dCBhbGwgcmlnaHQtdGhpbmtpbmcgcGVvcGxlIGluIHRoaXMgY291bnRyeSBhcmUg
-c2ljayBhbmQKdGlyZWQgb2YgYmVpbmcgdG9sZCB0aGF0IG9yZGluYXJ5IGRlY2Vu
-dCBwZW9wbGUgYXJlIGZlZCB1cCBpbiB0aGlzCmNvdW50cnkgd2l0aCBiZWluZyBz
-aWNrIGFuZCB0aXJlZC4gIEknbSBjZXJ0YWlubHkgbm90LiAgQnV0IEknbQpzaWNr
-IGFuZCB0aXJlZCBvZiBiZWluZyB0b2xkIHRoYXQgSSBhbS4KLSBNb250eSBQeXRo
-b24KiD8DBQBEDFJaLXJ8x2hpdzQRAkeCAKCZRBk2Pmx4w9h2LgosS0AppNNaWwCg
-iI5MyzgJpGTZtA/Jbk+/HP9ceOU=
-=8nLN
------END PGP MESSAGE-----
-")
-
-;; A standard message with two signatures (actually the same signature
-;; duplicated).
-(define msg_oolss_asc "
------BEGIN PGP MESSAGE-----
-
-kA0DAAIRLXJ8x2hpdzQBkA0DAAIRLXJ8x2hpdzQBrQEHYgNtc2dEDFJaSSB0aGlu
-ayB0aGF0IGFsbCByaWdodC10aGlua2luZyBwZW9wbGUgaW4gdGhpcyBjb3VudHJ5
-IGFyZSBzaWNrIGFuZAp0aXJlZCBvZiBiZWluZyB0b2xkIHRoYXQgb3JkaW5hcnkg
-ZGVjZW50IHBlb3BsZSBhcmUgZmVkIHVwIGluIHRoaXMKY291bnRyeSB3aXRoIGJl
-aW5nIHNpY2sgYW5kIHRpcmVkLiAgSSdtIGNlcnRhaW5seSBub3QuICBCdXQgSSdt
-CnNpY2sgYW5kIHRpcmVkIG9mIGJlaW5nIHRvbGQgdGhhdCBJIGFtLgotIE1vbnR5
-IFB5dGhvbgqIPwMFAEQMUlotcnzHaGl3NBECR4IAoJlEGTY+bHjD2HYuCixLQCmk
-01pbAKCIjkzLOAmkZNm0D8luT78c/1x45Yg/AwUARAxSWi1yfMdoaXc0EQJHggCg
-mUQZNj5seMPYdi4KLEtAKaTTWlsAoIiOTMs4CaRk2bQPyW5Pvxz/XHjl
-=KVw5
------END PGP MESSAGE-----
-")
-
-;; A standard message with two one-pass packet but only one signature
-;; packet
-(define bad_ools_asc "
------BEGIN PGP MESSAGE-----
-
-kA0DAAIRLXJ8x2hpdzQBkA0DAAIRLXJ8x2hpdzQBrQEHYgNtc2dEDFJaSSB0aGlu
-ayB0aGF0IGFsbCByaWdodC10aGlua2luZyBwZW9wbGUgaW4gdGhpcyBjb3VudHJ5
-IGFyZSBzaWNrIGFuZAp0aXJlZCBvZiBiZWluZyB0b2xkIHRoYXQgb3JkaW5hcnkg
-ZGVjZW50IHBlb3BsZSBhcmUgZmVkIHVwIGluIHRoaXMKY291bnRyeSB3aXRoIGJl
-aW5nIHNpY2sgYW5kIHRpcmVkLiAgSSdtIGNlcnRhaW5seSBub3QuICBCdXQgSSdt
-CnNpY2sgYW5kIHRpcmVkIG9mIGJlaW5nIHRvbGQgdGhhdCBJIGFtLgotIE1vbnR5
-IFB5dGhvbgqIPwMFAEQMUlotcnzHaGl3NBECR4IAoJlEGTY+bHjD2HYuCixLQCmk
-01pbAKCIjkzLOAmkZNm0D8luT78c/1x45Q==
-=1/ix
------END PGP MESSAGE-----
-")
-
-;; Standard cleartext signature
-(define msg_cls_asc "
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-I think that all right-thinking people in this country are sick and
-tired of being told that ordinary decent people are fed up in this
-country with being sick and tired. I'm certainly not. But I'm
-sick and tired of being told that I am.
-- - Monty Python
------BEGIN PGP SIGNATURE-----
-
-iD8DBQFEDVp1LXJ8x2hpdzQRAplUAKCMfpG3GPw/TLN52tosgXP5lNECkwCfQhAa
-emmev7IuQjWYrGF9Lxj+zj8=
-=qJsY
------END PGP SIGNATURE-----
-")
-
-;; Cleartext signature with two signatures
-(define msg_clss_asc "
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-What is the difference between a Turing machine and the modern computer?
-It's the same as that between Hillary's ascent of Everest and the
-establishment of a Hilton on its peak.
------BEGIN PGP SIGNATURE-----
-
-iD8DBQFEDVz6LXJ8x2hpdzQRAtkGAKCeMhNbHnh339fpjNj9owsYcC4zBwCfYO5l
-2u+KEfXX0FKyk8SMzLjZ536IPwMFAUQNXPr+GAsdqeOwshEC2QYAoPOWAiQm0EF/
-FWIAQUplk7JWbyRKAJ92ZJyJpWfzb0yc1s7MY65r2qEHrg==
-=1Xvv
------END PGP SIGNATURE-----
-")
-
-;; Two clear text signatures in a row
-(define msg_clsclss_asc_multiple (string-append msg_cls_asc msg_clss_asc))
-
-
-;; An Ed25519 cleartext message with an R parameter of only 247 bits
-;; so that the code to re-insert the stripped zero byte kicks in. The
-;; S parameter has 253 bits but that does not strip a full byte.
-;;
-;; Note that the message has a typo ("the the"), but this should not
-;; be fixed because it breaks this test.
-(define msg_ed25519_rshort "
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA256
-
-Dear Emily:
- I'm still confused as to what groups articles should be posted
-to. How about an example?
- -- Still Confused
-
-Dear Still:
- Ok. Let's say you want to report that Gretzky has been traded from
-the Oilers to the Kings. Now right away you might think rec.sport.hockey
-would be enough. WRONG. Many more people might be interested. This is a
-big trade! Since it's a NEWS article, it belongs in the news.* hierarchy
-as well. If you are a news admin, or there is one on your machine, try
-news.admin. If not, use news.misc.
- The Oilers are probably interested in geology, so try sci.physics.
-He is a big star, so post to sci.astro, and sci.space because they are also
-interested in stars. Next, his name is Polish sounding. So post to
-soc.culture.polish. But that group doesn't exist, so cross-post to
-news.groups suggesting it should be created. With this many groups of
-interest, your article will be quite bizarre, so post to talk.bizarre as
-well. (And post to comp.std.mumps, since they hardly get any articles
-there, and a \"comp\" group will propagate your article further.)
- You may also find it is more fun to post the article once in each
-group. If you list all the newsgroups in the same article, some newsreaders
-will only show the the article to the reader once! Don't tolerate this.
- -- Emily Postnews Answers Your Questions on Netiquette
------BEGIN PGP SIGNATURE-----
-
-iJEEARYIADoWIQSyHeq0+HX7PaQvHR0TlWNoKgINCgUCV772DhwccGF0cmljZS5s
-dW11bWJhQGV4YW1wbGUubmV0AAoJEBOVY2gqAg0KMAIA90EtUwAja0iJGpO91wyz
-GLh9pS5v495V0r94yU6uUyUA/RT/StyPWe1wbnEZuacZnLbUV6Yy/aTXCVAlxf0r
-TusO
-=vQ3f
------END PGP SIGNATURE-----
-")
-
-;; An Ed25519 cleartext message with an S parameter of only 248 bits
-;; so that the code to re-insert the stripped zero byte kicks in.
-(define msg_ed25519_sshort "
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA256
-
-All articles that coruscate with resplendence are not truly auriferous.
------BEGIN PGP SIGNATURE-----
-
-iJEEARYIADoWIQSyHeq0+HX7PaQvHR0TlWNoKgINCgUCV771QhwccGF0cmljZS5s
-dW11bWJhQGV4YW1wbGUubmV0AAoJEBOVY2gqAg0KHVEBAI66OPDYXKWO3r6SaFT+
-uxmh8x4ZerW41vMA9gkJ4AEKAPjoe/Z7fDqo1lCptIFutFAGbfNxcm/53prfx2fT
-GisM
-=L7sk
------END PGP SIGNATURE-----
-")
-
-
-
;; Fixme: We need more tests with manipulated cleartext signatures.
;;
diff --git a/tools/call-dirmngr.c b/tools/call-dirmngr.c
index 9e3e493..c219905 100644
--- a/tools/call-dirmngr.c
+++ b/tools/call-dirmngr.c
@@ -1,19 +1,20 @@
/* call-dirmngr.c - Interact with the Dirmngr.
* Copyright (C) 2016 g10 Code GmbH
+ * Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik
*
* 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 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.
*
- * GnuPG is distributed in the hope that it will be useful,
+ * 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.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
diff --git a/tools/call-dirmngr.h b/tools/call-dirmngr.h
index 32486b1..4da0145 100644
--- a/tools/call-dirmngr.h
+++ b/tools/call-dirmngr.h
@@ -1,19 +1,20 @@
/* call-dirmngr.h - Interact with the Dirmngr.
* Copyright (C) 2016 g10 Code GmbH
+ * Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik
*
* 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 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.
*
- * GnuPG is distributed in the hope that it will be useful,
+ * 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.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#ifndef GNUPG_TOOLS_CALL_DIRMNGR_H
diff --git a/tools/gpg-check-pattern.c b/tools/gpg-check-pattern.c
index 7197340..4db8f37 100644
--- a/tools/gpg-check-pattern.c
+++ b/tools/gpg-check-pattern.c
@@ -74,7 +74,7 @@ static ARGPARSE_OPTS opts[] = {
{ oCheck, "check", 0, "run only a syntax check on the patternfile" },
{ oNull, "null", 0, "input is expected to be null delimited" },
- {0}
+ ARGPARSE_end ()
};
diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c
index c578105..746aa53 100644
--- a/tools/gpg-wks-client.c
+++ b/tools/gpg-wks-client.c
@@ -1,19 +1,20 @@
/* gpg-wks-client.c - A client for the Web Key Service protocols.
* Copyright (C) 2016 Werner Koch
+ * Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik
*
* 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 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.
*
- * GnuPG is distributed in the hope that it will be useful,
+ * 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.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
@@ -137,8 +138,8 @@ my_strusage( int level )
switch (level)
{
- case 11: p = "gpg-wks-client (@GNUPG@)";
- break;
+ case 11: p = "gpg-wks-client"; break;
+ case 12: p = "@GNUPG@"; break;
case 13: p = VERSION; break;
case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = ("Please report bugs to <@EMAIL@>.\n"); break;
diff --git a/tools/gpg-wks-server.c b/tools/gpg-wks-server.c
index 4d3e24d..1633a20 100644
--- a/tools/gpg-wks-server.c
+++ b/tools/gpg-wks-server.c
@@ -1,19 +1,20 @@
/* gpg-wks-server.c - A server for the Web Key Service protocols.
* Copyright (C) 2016 Werner Koch
+ * Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik
*
* 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 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.
*
- * GnuPG is distributed in the hope that it will be useful,
+ * 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.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
@@ -62,6 +63,9 @@ enum cmd_and_opt_values
aReceive,
aCron,
aListDomains,
+ aInstallKey,
+ aRevokeKey,
+ aRemoveKey,
oGpgProgram,
oSend,
@@ -82,6 +86,12 @@ static ARGPARSE_OPTS opts[] = {
("run regular jobs")),
ARGPARSE_c (aListDomains, "list-domains",
("list configured domains")),
+ ARGPARSE_c (aInstallKey, "install-key",
+ "|FILE|install a key from FILE into the WKD"),
+ ARGPARSE_c (aRemoveKey, "remove-key",
+ "|ADDR|remove the key ADDR from the WKD"),
+ ARGPARSE_c (aRevokeKey, "revoke-key",
+ "|ADDR|mark the key ADDR in the WKD as revoked"),
ARGPARSE_group (301, ("@\nOptions:\n ")),
@@ -129,6 +139,9 @@ static gpg_error_t command_receive_cb (void *opaque,
const char *mediatype, estream_t fp,
unsigned int flags);
static gpg_error_t command_list_domains (void);
+static gpg_error_t command_install_key (const char *fname);
+static gpg_error_t command_remove_key (const char *mailaddr);
+static gpg_error_t command_revoke_key (const char *mailaddr);
static gpg_error_t command_cron (void);
@@ -141,8 +154,8 @@ my_strusage( int level )
switch (level)
{
- case 11: p = "gpg-wks-server (@GNUPG@)";
- break;
+ case 11: p = "gpg-wks-server"; break;
+ case 12: p = "@GNUPG@"; break;
case 13: p = VERSION; break;
case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = ("Please report bugs to <@EMAIL@>.\n"); break;
@@ -211,6 +224,9 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
case aReceive:
case aCron:
case aListDomains:
+ case aInstallKey:
+ case aRemoveKey:
+ case aRevokeKey:
cmd = pargs->r_opt;
break;
@@ -336,6 +352,24 @@ main (int argc, char **argv)
err = command_list_domains ();
break;
+ case aInstallKey:
+ if (argc != 1)
+ wrong_args ("--install-key FILE");
+ err = command_install_key (*argv);
+ break;
+
+ case aRemoveKey:
+ if (argc != 1)
+ wrong_args ("--remove-key MAILADDR");
+ err = command_remove_key (*argv);
+ break;
+
+ case aRevokeKey:
+ if (argc != 1)
+ wrong_args ("--revoke-key MAILADDR");
+ err = command_revoke_key (*argv);
+ break;
+
default:
usage (1);
err = gpg_error (GPG_ERR_BUG);
@@ -1861,3 +1895,30 @@ command_cron (void)
free_strlist (domaindirs);
return err;
}
+
+
+/* Install a single key into the WKD by reading FNAME. */
+static gpg_error_t
+command_install_key (const char *fname)
+{
+ (void)fname;
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+}
+
+
+/* Remove the key with mail address MAILADDR. */
+static gpg_error_t
+command_remove_key (const char *mailaddr)
+{
+ (void)mailaddr;
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+}
+
+
+/* Revoke the key with mail address MAILADDR. */
+static gpg_error_t
+command_revoke_key (const char *mailaddr)
+{
+ (void)mailaddr;
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+}
diff --git a/tools/gpg-wks.h b/tools/gpg-wks.h
index 3b28af4..f73c183 100644
--- a/tools/gpg-wks.h
+++ b/tools/gpg-wks.h
@@ -1,19 +1,20 @@
/* gpg-wks.h - Common definitions for wks server and client.
* Copyright (C) 2016 g10 Code GmbH
+ * Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik
*
* 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 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.
*
- * GnuPG is distributed in the hope that it will be useful,
+ * 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.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
index f608f7a..cfc9fa3 100644
--- a/tools/gpgconf-comp.c
+++ b/tools/gpgconf-comp.c
@@ -149,7 +149,7 @@ typedef enum
/* To be able to implement generic algorithms for the various
backends, we collect all information about them in this struct. */
-static struct
+static const struct
{
/* The name of the backend. */
const char *name;
@@ -256,7 +256,7 @@ typedef enum
/* For every argument, we record some information about it in the
following struct. */
-static struct
+static const struct
{
/* For every argument type exists a basic argument type that can be
used as a fallback for input and validation purposes. */
@@ -328,7 +328,7 @@ typedef enum
} gc_expert_level_t;
/* A description for each expert level. */
-static struct
+static const struct
{
const char *name;
} gc_level[] =
@@ -361,7 +361,7 @@ static struct
/* A human-readable description for each flag. */
-static struct
+static const struct
{
const char *name;
} gc_flag[] =
@@ -500,6 +500,10 @@ static gc_option_t gc_options_gpg_agent[] =
{ "enable-ssh-support", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
"gnupg", "enable ssh support",
GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
+ { "ssh-fingerprint-digest",
+ GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT,
+ "gnupg", "|ALGO|use ALGO to show ssh fingerprints",
+ GC_ARG_TYPE_STRING, GC_BACKEND_GPG_AGENT },
{ "enable-putty-support", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
"gnupg", "enable putty support",
GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
@@ -1070,7 +1074,7 @@ typedef enum
/* The information associated with each component. */
-static struct
+static const struct
{
/* The name of this component. Must not contain a colon (':')
character. */
diff --git a/tools/gpgconf.c b/tools/gpgconf.c
index 2236555..fefa2ff 100644
--- a/tools/gpgconf.c
+++ b/tools/gpgconf.c
@@ -105,7 +105,8 @@ static ARGPARSE_OPTS opts[] =
{ oBuilddir, "build-prefix", 2, "@" },
{ oNull, "null", 0, "@" },
{ oNoVerbose, "no-verbose", 0, "@"},
- {0}
+
+ ARGPARSE_end(),
};
diff --git a/tools/gpgsplit.c b/tools/gpgsplit.c
index b9787b1..674be62 100644
--- a/tools/gpgsplit.c
+++ b/tools/gpgsplit.c
@@ -75,7 +75,9 @@ static ARGPARSE_OPTS opts[] = {
{ oUncompress, "uncompress", 0, "uncompress a packet"},
{ oSecretToPublic, "secret-to-public", 0, "convert secret keys to public keys"},
{ oNoSplit, "no-split", 0, "write to stdout and don't actually split"},
-{0} };
+
+ ARGPARSE_end ()
+};
static const char *
diff --git a/tools/mime-maker.c b/tools/mime-maker.c
index 0332f31..d1241f3 100644
--- a/tools/mime-maker.c
+++ b/tools/mime-maker.c
@@ -1,19 +1,20 @@
/* mime-maker.c - Create MIME structures
* Copyright (C) 2016 g10 Code GmbH
+ * Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik
*
* 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 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.
*
- * GnuPG is distributed in the hope that it will be useful,
+ * 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.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
diff --git a/tools/mime-maker.h b/tools/mime-maker.h
index 7aebdbd..f2a76cd 100644
--- a/tools/mime-maker.h
+++ b/tools/mime-maker.h
@@ -1,19 +1,20 @@
/* mime-maker.h - Create MIME structures
* Copyright (C) 2016 g10 Code GmbH
+ * Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik
*
* 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 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.
*
- * GnuPG is distributed in the hope that it will be useful,
+ * 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.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
diff --git a/tools/mime-parser.c b/tools/mime-parser.c
index 08b0219..a151dc6 100644
--- a/tools/mime-parser.c
+++ b/tools/mime-parser.c
@@ -1,19 +1,20 @@
/* mime-parser.c - Parse MIME structures (high level rfc822 parser).
* Copyright (C) 2016 g10 Code GmbH
+ * Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik
*
* 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 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.
*
- * GnuPG is distributed in the hope that it will be useful,
+ * 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.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
diff --git a/tools/mime-parser.h b/tools/mime-parser.h
index 5dc0492..4152966 100644
--- a/tools/mime-parser.h
+++ b/tools/mime-parser.h
@@ -1,19 +1,20 @@
/* mime-parser.h - Parse MIME structures (high level rfc822 parser).
* Copyright (C) 2016 g10 Code GmbH
+ * Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik
*
* 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 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.
*
- * GnuPG is distributed in the hope that it will be useful,
+ * 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.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
diff --git a/tools/rfc822parse.c b/tools/rfc822parse.c
index 412599b..ab692bd 100644
--- a/tools/rfc822parse.c
+++ b/tools/rfc822parse.c
@@ -1,20 +1,20 @@
/* rfc822parse.c - Simple mail and MIME parser
- * Copyright (C) 1999, 2000 Werner Koch, Duesseldorf
- * Copyright (C) 2003, 2004 g10 Code GmbH
+ * Copyright (C) 1999, 2000 Werner Koch, Duesseldorf
+ * 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 Lesser General Public License
- * as published by the Free Software Foundation; either version 3 of
+ * This file 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,
+ * 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
+ * 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 <https://www.gnu.org/licenses/>.
- */
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+g */
/* According to RFC822 binary zeroes are allowed at many places. We do
diff --git a/tools/rfc822parse.h b/tools/rfc822parse.h
index 966c91e..177d827 100644
--- a/tools/rfc822parse.h
+++ b/tools/rfc822parse.h
@@ -1,19 +1,19 @@
/* rfc822parse.h - Simple mail and MIME parser
- * Copyright (C) 1999 Werner Koch, Duesseldorf
- * Copyright (C) 2003 g10 Code GmbH
+ * Copyright (C) 1999 Werner Koch, Duesseldorf
+ * Copyright (C) 2003 g10 Code GmbH
*
- * 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 3 of
+ * This file 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,
+ * 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
+ * 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 <https://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#ifndef RFC822PARSE_H
diff --git a/tools/send-mail.c b/tools/send-mail.c
index fb1a9d0..9f07c7a 100644
--- a/tools/send-mail.c
+++ b/tools/send-mail.c
@@ -1,19 +1,20 @@
/* send-mail.c - Invoke sendmail or other delivery tool.
* Copyright (C) 2016 g10 Code GmbH
+ * Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik
*
* 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 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.
*
- * GnuPG is distributed in the hope that it will be useful,
+ * 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.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
diff --git a/tools/send-mail.h b/tools/send-mail.h
index 4d8ae98..b565a18 100644
--- a/tools/send-mail.h
+++ b/tools/send-mail.h
@@ -1,19 +1,20 @@
/* send-mail.h - Invoke sendmail or other delivery tool.
* Copyright (C) 2016 g10 Code GmbH
+ * Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik
*
* 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 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.
*
- * GnuPG is distributed in the hope that it will be useful,
+ * 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.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
diff --git a/tools/symcryptrun.c b/tools/symcryptrun.c
index 54976ca..c5780fd 100644
--- a/tools/symcryptrun.c
+++ b/tools/symcryptrun.c
@@ -185,7 +185,7 @@ static ARGPARSE_OPTS opts[] =
{ oHomedir, "homedir", 2, "@" },
{ oNoOptions, "no-options", 0, "@" },/* shortcut for --options /dev/null */
- {0}
+ ARGPARSE_end ()
};
diff --git a/tools/wks-receive.c b/tools/wks-receive.c
index 49a1517..e67da62 100644
--- a/tools/wks-receive.c
+++ b/tools/wks-receive.c
@@ -1,19 +1,20 @@
/* wks-receive.c - Receive a WKS mail
* Copyright (C) 2016 g10 Code GmbH
+ * Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik
*
* 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 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.
*
- * GnuPG is distributed in the hope that it will be useful,
+ * 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.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
diff --git a/tools/wks-util.c b/tools/wks-util.c
index 8eab834..46ad5c2 100644
--- a/tools/wks-util.c
+++ b/tools/wks-util.c
@@ -1,20 +1,18 @@
/* wks-utils.c - Common helper functions for wks tools
* Copyright (C) 2016 g10 Code GmbH
+ * Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik
*
* 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 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.
*
- * GnuPG is distributed in the hope that it will be useful,
+ * 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 <https://www.gnu.org/licenses/>.
+ * GNU Lesser General Public License for more details.
*/
#include <config.h>