Imported Upstream version 2.2.18 upstream/2.2.18
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 9 Feb 2021 07:00:49 +0000 (16:00 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 9 Feb 2021 07:00:49 +0000 (16:00 +0900)
85 files changed:
NEWS
agent/call-pinentry.c
build-aux/speedo.mk
common/name-value.c
common/sexputil.c
common/util.h
configure.ac
dirmngr/Makefile.am
dirmngr/dirmngr-status.h [new file with mode: 0644]
dirmngr/dirmngr.c
dirmngr/dirmngr.h
dirmngr/dns-stuff.c
dirmngr/dns-stuff.h
dirmngr/http.c
dirmngr/http.h
dirmngr/ks-engine-hkp.c
dirmngr/ks-engine-http.c
dirmngr/t-support.c [new file with mode: 0644]
doc/DETAILS
doc/dirmngr.texi
doc/gpg.texi
doc/tools.texi
g10/call-agent.c
g10/call-agent.h
g10/call-dirmngr.c
g10/card-util.c
g10/delkey.c
g10/getkey.c
g10/gpg.c
g10/import.c
g10/keydb.c
g10/keydb.h
g10/keygen.c
g10/keylist.c
g10/keyring.c
g10/keyserver.c
g10/main.h
g10/misc.c
g10/options.h
g10/parse-packet.c
g10/pubkey-enc.c
g10/sig-check.c
g10/sign.c
g10/skclist.c
g10/trustdb.c
kbx/keybox-dump.c
kbx/keybox-init.c
kbx/keybox-update.c
kbx/keybox.h
po/ca.po
po/cs.po
po/da.po
po/de.po
po/el.po
po/eo.po
po/es.po
po/et.po
po/fi.po
po/fr.po
po/gl.po
po/hu.po
po/id.po
po/it.po
po/ja.po
po/nb.po
po/pl.po
po/pt.po
po/ro.po
po/ru.po
po/sk.po
po/sv.po
po/tr.po
po/uk.po
po/zh_CN.po
po/zh_TW.po
scd/app-nks.c
scd/app-openpgp.c
scd/ccid-driver.c
scd/ccid-driver.h
sm/call-agent.c
sm/certreqgen-ui.c
sm/decrypt.c
tests/openpgp/defs.scm
tools/gpgconf-comp.c
tools/wks-util.c

diff --git a/NEWS b/NEWS
index cf5b04d..aedead0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,73 @@
+Noteworthy changes in version 2.2.18 (2019-11-25)
+-------------------------------------------------
+
+  * gpg: Changed the way keys are detected on a smartcards; this
+    allows the use of non-OpenPGP cards.  In the case of a not very
+    likely regression the new option --use-only-openpgp-card is
+    available.  [#4681]
+
+  * gpg: The commands --full-gen-key and --quick-gen-key now allow
+    direct key generation from supported cards.  [#4681]
+
+  * gpg: Prepare against chosen-prefix SHA-1 collisions in key
+    signatures.  This change removes all SHA-1 based key signature
+    newer than 2019-01-19 from the web-of-trust.  Note that this
+    includes all key signature created with dsa1024 keys.  The new
+    option --allow-weak-key-signatues can be used to override the new
+    and safer behaviour.  [#4755,CVE-2019-14855]
+
+  * gpg: Improve performance for import of large keyblocks.  [#4592]
+
+  * gpg: Implement a keybox compression run.  [#4644]
+
+  * gpg: Show warnings from dirmngr about redirect and certificate
+    problems (details require --verbose as usual).
+
+  * gpg: Allow to pass the empty string for the passphrase if the
+    '--passphase=' syntax is used.  [#4633]
+
+  * gpg: Fix printing of the KDF object attributes.
+
+  * gpg: Avoid surprises with --locate-external-key and certain
+    --auto-key-locate settings.  [#4662]
+
+  * gpg: Improve selection of best matching key.  [#4713]
+
+  * gpg: Delete key binding signature when deletring a subkey.
+    [#4665,#4457]
+
+  * gpg: Fix a potential loss of key sigantures during import with
+    self-sigs-only active.  [#4628]
+
+  * gpg: Silence "marked as ultimately trusted" diagnostics if
+    option --quiet is used.  [#4634]
+
+  * gpg: Silence some diagnostics during in key listsing even with
+    option --verbose.  [#4627]
+
+  * gpg, gpgsm: Change parsing of agent's pkdecrypt results.  [#4652]
+
+  * gpgsm: Support AES-256 keys.
+
+  * gpgsm: Fix a bug in triggering a keybox compression run if
+    --faked-system-time is used.
+
+  * dirmngr: System CA certificates are no longer used for the SKS
+    pool if GNUTLS instead of NTBTLS is used as TLS library.  [#4594]
+
+  * dirmngr: On Windows detect usability of IPv4 and IPv6 interfaces
+    to avoid long timeouts.  [#4165]
+
+  * scd: Fix BWI value for APDU level transfers to make Gemalto Ezio
+    Shield and Trustica Cryptoucan work.  [#4654,#4566]
+
+  * wkd: gpg-wks-client --install-key now installs the required policy
+    file.
+
+  Release-info: https://dev.gnupg.org/T4684
+  See-also: gnupg-announce/2019q4/000442.html
+
+
 Noteworthy changes in version 2.2.17 (2019-07-09)
 -------------------------------------------------
 
index 1f3bd52..b0b5bcb 100644 (file)
@@ -191,6 +191,37 @@ unlock_pinentry (ctrl_t ctrl, gpg_error_t rc)
 }
 
 
+/* Helper for at_fork_cb which can also be called by the parent to
+ * show shich envvars will be set.  */
+static void
+atfork_core (ctrl_t ctrl, int debug_mode)
+{
+  int iterator = 0;
+  const char *name, *assname, *value;
+
+  while ((name = session_env_list_stdenvnames (&iterator, &assname)))
+    {
+      /* For all new envvars (!ASSNAME) and the two medium old ones
+       * which do have an assuan name but are conveyed using
+       * environment variables, update the environment of the forked
+       * process.  */
+      if (!assname
+          || !strcmp (name, "XAUTHORITY")
+          || !strcmp (name, "PINENTRY_USER_DATA"))
+        {
+          value = session_env_getenv (ctrl->session_env, name);
+          if (value)
+            {
+              if (debug_mode)
+                log_debug ("pinentry: atfork used setenv(%s,%s)\n",name,value);
+              else
+                gnupg_setenv (name, value, 1);
+            }
+        }
+    }
+}
+
+
 /* To make sure we leave no secrets in our image after forking of the
    pinentry, we use this callback. */
 static void
@@ -200,26 +231,8 @@ atfork_cb (void *opaque, int where)
 
   if (!where)
     {
-      int iterator = 0;
-      const char *name, *assname, *value;
-
       gcry_control (GCRYCTL_TERM_SECMEM);
-
-      while ((name = session_env_list_stdenvnames (&iterator, &assname)))
-        {
-          /* For all new envvars (!ASSNAME) and the two medium old
-             ones which do have an assuan name but are conveyed using
-             environment variables, update the environment of the
-             forked process.  */
-          if (!assname
-              || !strcmp (name, "XAUTHORITY")
-              || !strcmp (name, "PINENTRY_USER_DATA"))
-            {
-              value = session_env_getenv (ctrl->session_env, name);
-              if (value)
-                gnupg_setenv (name, value, 1);
-            }
-        }
+      atfork_core (ctrl, 0);
     }
 }
 
@@ -406,6 +419,9 @@ start_pinentry (ctrl_t ctrl)
   if (DBG_IPC)
     log_debug ("connection to PIN entry established\n");
 
+  if (opt.debug_pinentry)
+    atfork_core (ctrl, 1);
+
   value = session_env_getenv (ctrl->session_env, "PINENTRY_USER_DATA");
   if (value != NULL)
     {
@@ -616,7 +632,7 @@ start_pinentry (ctrl_t ctrl)
 
   /* Ask the pinentry for its version and flavor and store that as a
    * string in MB.  This information is useful for helping users to
-   * figure out Pinentry problems.  Noet that "flavor" may also return
+   * figure out Pinentry problems.  Note that "flavor" may also return
    * a status line with the features; we use a dedicated handler for
    * that.  */
   {
@@ -1078,7 +1094,8 @@ agent_askpin (ctrl_t ctrl,
         {
           /* TRANSLATORS: The string is appended to an error message in
              the pinentry.  The %s is the actual error message, the
-             two %d give the current and maximum number of tries. */
+             two %d give the current and maximum number of tries.
+             Do not translate the "SETERROR" keyword. */
           snprintf (line, DIM(line), L_("SETERROR %s (try %d of %d)"),
                     errtext, pininfo->failed_tries+1, pininfo->max_tries);
           rc = assuan_transact (entry_ctx, line,
index d1f9800..fcb7b27 100644 (file)
@@ -1259,7 +1259,8 @@ installer: all w32_insthelpers $(w32src)/inst-options.ini $(bdir)/README.txt
            done; \
          fi \
         )
-       $(MAKENSIS) -V2 \
+       $(MAKENSIS) -V2 $$($(MAKENSIS) -version \
+                           | grep -q ^v3 && echo "-INPUTCHARSET CP1252 ") \
                     -DINST_DIR=$(idir) \
                     -DINST6_DIR=$(idir6) \
                     -DBUILD_DIR=$(bdir) \
index 5094acd..0129f1b 100644 (file)
@@ -195,11 +195,11 @@ assert_raw_value (nve_t entry)
          size_t i;
 
          /* Find a suitable space to break on.  */
-         for (i = linelen - 1; linelen - i < 30 && linelen - i > offset; i--)
-           if (ascii_isspace (entry->value[i]))
+         for (i = linelen - 1; linelen - i < 30; i--)
+           if (ascii_isspace (entry->value[offset+i]))
              break;
 
-         if (ascii_isspace (entry->value[i]))
+         if (ascii_isspace (entry->value[offset+i]))
            {
              /* Found one.  */
              amount = i;
index 5e51f68..e8c8a34 100644 (file)
@@ -581,9 +581,9 @@ get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen)
 
 /* Given the public key S_PKEY, return a new buffer with a descriptive
  * string for its algorithm.  This function may return NULL on memory
- * error. */
+ * error.  If R_ALGOID is not NULL the gcrypt algo id is stored there. */
 char *
-pubkey_algo_string (gcry_sexp_t s_pkey)
+pubkey_algo_string (gcry_sexp_t s_pkey, enum gcry_pk_algos *r_algoid)
 {
   const char *prefix;
   gcry_sexp_t l1;
@@ -591,6 +591,9 @@ pubkey_algo_string (gcry_sexp_t s_pkey)
   int algo;
   char *result;
 
+  if (r_algoid)
+    *r_algoid = 0;
+
   l1 = gcry_sexp_find_token (s_pkey, "public-key", 0);
   if (!l1)
     return xtrystrdup ("E_no_key");
@@ -632,6 +635,8 @@ pubkey_algo_string (gcry_sexp_t s_pkey)
   else
     result = xtryasprintf ("X_algo_%d", algo);
 
+  if (r_algoid)
+    *r_algoid = algo;
   xfree (algoname);
   return result;
 }
index 27f565b..2472222 100644 (file)
@@ -199,7 +199,7 @@ gpg_error_t get_rsa_pk_from_canon_sexp (const unsigned char *keydata,
 int get_pk_algo_from_key (gcry_sexp_t key);
 int get_pk_algo_from_canon_sexp (const unsigned char *keydata,
                                  size_t keydatalen);
-char *pubkey_algo_string (gcry_sexp_t s_pkey);
+char *pubkey_algo_string (gcry_sexp_t s_pkey, enum gcry_pk_algos *r_algoid);
 
 /*-- convert.c --*/
 int hex2bin (const char *string, void *buffer, size_t length);
index 65ae523..83dbc26 100644 (file)
@@ -28,7 +28,7 @@ min_automake_version="1.14"
 m4_define([mym4_package],[gnupg])
 m4_define([mym4_major], [2])
 m4_define([mym4_minor], [2])
-m4_define([mym4_micro], [17])
+m4_define([mym4_micro], [18])
 
 # 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
index 081f723..098e711 100644 (file)
@@ -62,7 +62,7 @@ dirmngr_SOURCES = dirmngr.c dirmngr.h server.c crlcache.c crlfetch.c  \
        domaininfo.c \
        workqueue.c \
        loadswdb.c \
-       cdb.h cdblib.c misc.c dirmngr-err.h  \
+       cdb.h cdblib.c misc.c dirmngr-err.h dirmngr-status.h \
        ocsp.c ocsp.h validate.c validate.h  \
        dns-stuff.c dns-stuff.h \
        http.c http.h http-common.c http-common.h http-ntbtls.c \
@@ -111,7 +111,7 @@ dirmngr_client_LDADD = $(libcommon) \
 dirmngr_client_LDFLAGS = $(extra_bin_ldflags)
 
 
-t_common_src = t-support.h
+t_common_src = t-support.h t-support.c
 if USE_LIBDNS
 t_common_src += dns.c dns.h
 endif
diff --git a/dirmngr/dirmngr-status.h b/dirmngr/dirmngr-status.h
new file mode 100644 (file)
index 0000000..2c3fd78
--- /dev/null
@@ -0,0 +1,39 @@
+/* dirmngr-status.h - Status code helper functions for dirmnmgr.
+ * Copyright (C) 2004, 2014, 2015, 2018 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/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0+
+ */
+
+/* We keep them separate so that we don't always need to include the
+ * entire dirmngr.h */
+
+#ifndef DIRMNGR_STATUS_H
+#define DIRMNGR_STATUS_H
+
+
+/*-- server.c --*/
+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_helpf (ctrl_t ctrl, const char *format,
+                                  ...) GPGRT_ATTR_PRINTF(2,3);
+gpg_error_t dirmngr_status_printf (ctrl_t ctrl, const char *keyword,
+                                   const char *format,
+                                   ...) GPGRT_ATTR_PRINTF(3,4);
+
+
+#endif /* DIRMNGR_STATUS_H */
index 667308c..998a605 100644 (file)
@@ -1956,6 +1956,7 @@ housekeeping_thread (void *arg)
   memset (&ctrlbuf, 0, sizeof ctrlbuf);
   dirmngr_init_default_ctrl (&ctrlbuf);
 
+  dns_stuff_housekeeping ();
   ks_hkp_housekeeping (curtime);
   if (network_activity_seen)
     {
index 5189f93..1663ed1 100644 (file)
@@ -36,6 +36,7 @@
 #include "../common/sysutils.h" /* (gnupg_fd_t) */
 #include "../common/asshelp.h"  /* (assuan_context_t) */
 #include "../common/i18n.h"
+#include "dirmngr-status.h"
 #include "http.h"     /* (parsed_uri_t) */
 
 /* This objects keeps information about a particular LDAP server and
@@ -229,15 +230,10 @@ gpg_error_t get_istrusted_from_client (ctrl_t ctrl, const char *hexfpr);
 int dirmngr_assuan_log_monitor (assuan_context_t ctx, unsigned int cat,
                                 const char *msg);
 void start_command_handler (gnupg_fd_t fd, unsigned int session_id);
-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_helpf (ctrl_t ctrl, const char *format,
-                                  ...) GPGRT_ATTR_PRINTF(2,3);
-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);
 
+/* (See also dirmngr-status.h)  */
+
 /*-- http-ntbtls.c --*/
 /* Note that we don't use a callback for gnutls.  */
 
index a5087e5..4a50d75 100644 (file)
@@ -148,6 +148,15 @@ static char tor_nameserver[40+20];
 static char tor_socks_user[30];
 static char tor_socks_password[20];
 
+/* To avoid checking the interface too often we cache the result.  */
+static struct
+{
+  unsigned int valid:1;
+  unsigned int v4:1;
+  unsigned int v6:1;
+} cached_inet_support;
+
+
 
 #ifdef USE_LIBDNS
 /* Libdns gobal data.  */
@@ -676,6 +685,21 @@ reload_dns_stuff (int force)
 #else
   (void)force;
 #endif
+
+  /* We also flush the IPv4/v6 support flag cache.  */
+  cached_inet_support.valid = 0;
+}
+
+
+/* Called from time to time from the housekeeping thread.  */
+void
+dns_stuff_housekeeping (void)
+{
+  /* With the current housekeeping interval of 10 minutes we flush
+   * that case so that a new or removed interface will be detected not
+   * later than 10 minutes after it changed.  This way the user does
+   * not need a reload.  */
+  cached_inet_support.valid = 0;
 }
 
 
@@ -2372,3 +2396,83 @@ get_dns_cname (const char *name, char **r_cname)
                err ? gpg_strerror (err) : *r_cname);
   return err;
 }
+
+
+/* Check whether the machine has any usable inet devices up and
+ * running.  We put this into dns because on Windows this is
+ * implemented using getaddrinfo and thus easiest done here.  */
+void
+check_inet_support (int *r_v4, int *r_v6)
+{
+  if (cached_inet_support.valid)
+    {
+      *r_v4 = cached_inet_support.v4;
+      *r_v6 = cached_inet_support.v6;
+      return;
+    }
+
+  *r_v4 = *r_v6 = 0;
+
+#ifdef HAVE_W32_SYSTEM
+  {
+    gpg_error_t err;
+    int ret;
+    struct addrinfo *aibuf = NULL;
+    struct addrinfo *ai;
+
+    ret = getaddrinfo ("..localmachine", NULL, NULL, &aibuf);
+    if (ret)
+      {
+        err = map_eai_to_gpg_error (ret);
+        log_error ("%s: getaddrinfo failed: %s\n",__func__, gpg_strerror (err));
+        aibuf = NULL;
+      }
+
+    for (ai = aibuf; ai; ai = ai->ai_next)
+      {
+        if (opt_debug)
+          {
+            log_debug ("%s:  family: %d\n", __func__, ai->ai_family);
+            if (ai->ai_family == AF_INET6 || ai->ai_family == AF_INET)
+              {
+                char buffer[46];
+                DWORD buflen;
+                buflen = sizeof buffer;
+                if (WSAAddressToString (ai->ai_addr, (DWORD)ai->ai_addrlen,
+                                        NULL, buffer, &buflen))
+                  log_debug ("%s: WSAAddressToString failed: ec=%u\n",
+                             __func__, (unsigned int)WSAGetLastError ());
+                else
+                  log_debug ("%s:     addr: %s\n", __func__, buffer);
+              }
+          }
+        if (ai->ai_family == AF_INET6)
+          {
+            struct sockaddr_in6 *v6addr = (struct sockaddr_in6 *)ai->ai_addr;
+            if (!IN6_IS_ADDR_LINKLOCAL (&v6addr->sin6_addr))
+              *r_v6 = 1;
+          }
+        else if (ai->ai_family == AF_INET)
+          {
+            *r_v4 = 1;
+          }
+      }
+
+    if (aibuf)
+      freeaddrinfo (aibuf);
+  }
+#else /*!HAVE_W32_SYSTEM*/
+  {
+    /* For now we assume that we have both protocols.  */
+    *r_v4 = *r_v6 = 1;
+  }
+#endif /*!HAVE_W32_SYSTEM*/
+
+  if (opt_verbose)
+    log_info ("detected interfaces:%s%s\n",
+              *r_v4? " IPv4":"", *r_v6? " IPv6":"");
+
+  cached_inet_support.valid = 1;
+  cached_inet_support.v4 = *r_v4;
+  cached_inet_support.v6 = *r_v6;
+}
index 612b2e5..a9f9651 100644 (file)
@@ -134,6 +134,9 @@ void set_dns_nameserver (const char *ipaddr);
 /* SIGHUP action handler for this module.  */
 void reload_dns_stuff (int force);
 
+/* Housekeeping for this module.  */
+void dns_stuff_housekeeping (void);
+
 void free_dns_addrinfo (dns_addrinfo_t ai);
 
 /* Function similar to getaddrinfo.  */
@@ -166,4 +169,8 @@ gpg_error_t get_dns_srv (const char *name,
                          struct srventry **list, unsigned int *r_count);
 
 
+/* Store true in the variable if such an IP interface is usable.  */
+void check_inet_support (int *r_v4, int *r_v6);
+
+
 #endif /*GNUPG_DIRMNGR_DNS_STUFF_H*/
index d2456c6..4a47c98 100644 (file)
 #include "../common/i18n.h"
 #include "../common/sysutils.h" /* (gnupg_fd_t) */
 #include "dns-stuff.h"
+#include "dirmngr-status.h"    /* (dirmngr_status_printf)  */
 #include "http.h"
 #include "http-common.h"
 
@@ -791,6 +792,8 @@ http_session_new (http_session_t *r_session,
                         pemname, gnutls_strerror (rc));
             xfree (pemname);
           }
+
+        add_system_cas = 0;
       }
 
     /* Add configured certificates to the session.  */
@@ -2901,7 +2904,7 @@ connect_server (const char *server, unsigned short port,
   unsigned int srvcount = 0;
   int hostfound = 0;
   int anyhostaddr = 0;
-  int srv, connected;
+  int srv, connected, v4_valid, v6_valid;
   gpg_error_t last_err = 0;
   struct srventry *serverlist = NULL;
 
@@ -2911,6 +2914,8 @@ connect_server (const char *server, unsigned short port,
   init_sockets ();
 #endif /*Windows*/
 
+  check_inet_support (&v4_valid, &v6_valid);
+
   /* Onion addresses require special treatment.  */
   if (is_onion_address (server))
     {
@@ -2988,9 +2993,11 @@ connect_server (const char *server, unsigned short port,
 
       for (ai = aibuf; ai && !connected; ai = ai->next)
         {
-          if (ai->family == AF_INET && (flags & HTTP_FLAG_IGNORE_IPv4))
+          if (ai->family == AF_INET
+              && ((flags & HTTP_FLAG_IGNORE_IPv4) || !v4_valid))
             continue;
-          if (ai->family == AF_INET6 && (flags & HTTP_FLAG_IGNORE_IPv6))
+          if (ai->family == AF_INET6
+              && ((flags & HTTP_FLAG_IGNORE_IPv6) || !v6_valid))
             continue;
 
           if (sock != ASSUAN_INVALID_FD)
@@ -3622,13 +3629,23 @@ http_prepare_redirect (http_redir_info_t *info, unsigned int status_code,
    * https address. */
   if (info->orig_onion && !locuri->onion)
     {
+      dirmngr_status_printf (info->ctrl, "WARNING",
+                             "http_redirect %u"
+                             " redirect from onion to non-onion address"
+                             " rejected",
+                             err);
       http_release_parsed_uri (locuri);
       return gpg_error (GPG_ERR_FORBIDDEN);
     }
   if (!info->allow_downgrade && info->orig_https && !locuri->use_tls)
     {
+      err = gpg_error (GPG_ERR_FORBIDDEN);
+      dirmngr_status_printf (info->ctrl, "WARNING",
+                             "http_redirect %u"
+                             " redirect '%s' to '%s' rejected",
+                             err, info->orig_url, location);
       http_release_parsed_uri (locuri);
-      return gpg_error (GPG_ERR_FORBIDDEN);
+      return err;
     }
 
   if (info->trust_location)
@@ -3708,6 +3725,10 @@ http_prepare_redirect (http_redir_info_t *info, unsigned int status_code,
       http_release_parsed_uri (locuri);
       if (!info->silent)
         log_info (_("redirection changed to '%s'\n"), newurl);
+      dirmngr_status_printf (info->ctrl, "WARNING",
+                             "http_redirect_cleanup %u"
+                             " changed from '%s' to '%s'",
+                             0, info->orig_url, newurl);
     }
 
   *r_url = newurl;
index 2bad63d..e81aef2 100644 (file)
@@ -32,6 +32,7 @@
 #define GNUPG_COMMON_HTTP_H
 
 #include <gpg-error.h>
+#include "../common/fwddecl.h"
 
 struct uri_tuple_s
 {
@@ -106,6 +107,7 @@ typedef struct http_context_s *http_t;
 struct http_redir_info_s
 {
   unsigned int redirects_left;   /* Number of still possible redirects.    */
+  ctrl_t ctrl;                   /* The usual connection info or NULL.     */
   const char *orig_url;          /* The original requested URL.            */
   unsigned int orig_onion:1;     /* Original request was an onion address. */
   unsigned int orig_https:1;     /* Original request was a http address.   */
index a8b1ec2..fef752c 100644 (file)
@@ -1173,6 +1173,7 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
   err = http_parse_uri (&uri, request, 0);
   if (err)
     goto leave;
+  redirinfo.ctrl       = ctrl;
   redirinfo.orig_url   = request;
   redirinfo.orig_onion = uri->onion;
   redirinfo.allow_downgrade = 1;
index a9600db..c96625d 100644 (file)
@@ -78,10 +78,12 @@ ks_http_fetch (ctrl_t ctrl, const char *url, unsigned int flags,
   estream_t fp = NULL;
   char *request_buffer = NULL;
   parsed_uri_t uri = NULL;
+  parsed_uri_t helpuri = NULL;
 
   err = http_parse_uri (&uri, url, 0);
   if (err)
     goto leave;
+  redirinfo.ctrl       = ctrl;
   redirinfo.orig_url   = url;
   redirinfo.orig_onion = uri->onion;
   redirinfo.orig_https = uri->use_tls;
@@ -133,9 +135,25 @@ ks_http_fetch (ctrl_t ctrl, const char *url, unsigned int flags,
     }
   if (err)
     {
-      /* Fixme: After a redirection we show the old host name.  */
       log_error (_("error connecting to '%s': %s\n"),
                  url, gpg_strerror (err));
+      if (gpg_err_code (err) == GPG_ERR_WRONG_NAME
+          && gpg_err_source (err) == GPG_ERR_SOURCE_TLS)
+        {
+          const char *errhostname;
+
+          http_release_parsed_uri (helpuri);
+          if (http_parse_uri (&helpuri, url, 0))
+            errhostname = url; /* On parse error we use the full URL. */
+          else
+            errhostname = helpuri->host? helpuri->host : "?";
+
+          dirmngr_status_printf (ctrl, "NOTE",
+                                 "tls_cert_error %u"
+                                 " bad cert for '%s': %s",
+                                 err, errhostname,
+                                 "Hostname does not match the certificate");
+        }
       goto leave;
     }
 
@@ -202,5 +220,6 @@ ks_http_fetch (ctrl_t ctrl, const char *url, unsigned int flags,
   http_session_release (session);
   xfree (request_buffer);
   http_release_parsed_uri (uri);
+  http_release_parsed_uri (helpuri);
   return err;
 }
diff --git a/dirmngr/t-support.c b/dirmngr/t-support.c
new file mode 100644 (file)
index 0000000..fc9546a
--- /dev/null
@@ -0,0 +1,43 @@
+/* t-support.c - Module test support (stubs etc).
+ * Copyright (C) 2018 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/>.
+ * SPDX-License-Identifier: GPL-3.0+
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+
+#include "../common/util.h"
+#include "dirmngr-status.h"
+#include "t-support.h"
+
+
+
+/* Stub for testing. See server.c for the real implementation.  */
+gpg_error_t
+dirmngr_status_printf (ctrl_t ctrl, const char *keyword,
+                       const char *format, ...)
+{
+  (void)ctrl;
+  (void)keyword;
+  (void)format;
+
+  return 0;
+}
index dea9d42..7933863 100644 (file)
@@ -634,7 +634,10 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
     This indicates the length of the plaintext that is about to be
     written.  Note that if the plaintext packet has partial length
     encoding it is not possible to know the length ahead of time.  In
-    that case, this status tag does not appear.
+    that case, this status tag does not appear.  The length is only
+    exact for binary formats; other formats ('t', 'u') may do post
+    processing like line ending conversion so that the actual number
+    of bytes written may be differ.
 
 *** ATTRIBUTE <arguments>
     The list or arguments are:
@@ -1043,10 +1046,14 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
     numerical error code and an underscore; e.g.: "151011327_EOF".
 *** WARNING <location> <error code> [<text>]
     This is a generic warning status message, it might be followed by
-    error location specific data. <error code> and <location>
-    should not contain spaces.  The error code is a either a string
-    commencing with a letter or such a string prefixed with a
-    numerical error code and an underscore; e.g.: "151011327_EOF".
+    error location specific data. <location> and <error code> may not
+    contain spaces.  The <location> may be used to indicate a class of
+    warnings.  The error code is a either a string commencing with a
+    letter or such a string prefixed with a numerical error code and
+    an underscore; e.g.: "151011327_EOF".
+*** NOTE <location> <error code> [<text>]
+    This is a generic info status message the same syntax as for
+    WARNING messages is used.
 *** SUCCESS [<location>]
     Positive confirmation that an operation succeeded.  It is used
     similar to ISO-C's EXIT_SUCCESS.  <location> is optional but if
@@ -1566,6 +1573,7 @@ Description of some debug flags:
    | ecc/*   | 11 | ECC (set your own capabilities) |
    | ecc/e   | 12 | ECC (encrypt only)              |
    | keygrip | 13 | Existing key                    |
+   | cardkey | 14 | Existing key from card          |
 
    If one of the "foo/*" names are used a "keygen.flags" prompt needs
    to be answered as well.  Instead of toggling the predefined flags,
index 4345e36..ba4f159 100644 (file)
@@ -260,7 +260,8 @@ on startup or after reloading dirmngr.
 This option forces the use of the system's standard DNS resolver code.
 This is mainly used for debugging.  Note that on Windows a standard
 resolver is not used and all DNS access will return the error ``Not
-Implemented'' if this function is used.
+Implemented'' if this option is used.  Using this together with enabled
+Tor mode returns the error ``Not Enabled''.
 
 @item --recursive-resolver
 @opindex recursive-resolver
index 8a88b11..12bc2d7 100644 (file)
@@ -113,9 +113,12 @@ only one command is allowed.  Generally speaking, irrelevant options
 are silently ignored, and may not be checked for correctness.
 
 @command{@gpgname} may be run with no commands. In this case it will
-perform a reasonable action depending on the type of file it is given
-as input (an encrypted message is decrypted, a signature is verified,
-a file containing keys is listed, etc.).
+print a warning perform a reasonable action depending on the type of
+file it is given as input (an encrypted message is decrypted, a
+signature is verified, a file containing keys is listed, etc.).
+
+If you run into any problems, please add the option @option{--verbose}
+to the invocation to see more diagnostics.
 
 
 @menu
@@ -198,7 +201,7 @@ Make a detached signature.
 @opindex encrypt
 Encrypt data to one or more public keys. This command may be combined
 with @option{--sign} (to sign and encrypt a message),
-@option{--symmetric} (to encrypt a message that can decrypted using a
+@option{--symmetric} (to encrypt a message that can be decrypted using a
 secret key or a passphrase), or @option{--sign} and
 @option{--symmetric} together (for a signed message that can be
 decrypted using a secret key or a passphrase).  @option{--recipient}
@@ -683,6 +686,15 @@ 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.
 
+To create an OpenPGP key from the keys available on the currently
+inserted smartcard, the special string ``card'' can be used for
+@var{algo}.  If the card features an encryption and a signing key, gpg
+will figure them out and creates an OpenPGP key consisting of the
+usual primary key and one subkey.  This works only with certain
+smartcards.  Note that the interactive @option{--full-gen-key} command
+allows to do the same but with greater flexibility in the selection of
+the smartcard keys.
+
 Note that it is possible to create a primary key and a subkey using
 non-default algorithms by using ``default'' and changing the default
 parameters using the option @option{--default-new-key-algo}.
@@ -2354,12 +2366,14 @@ opposite meaning. The options are:
   command "clean" after import. Defaults to no.
 
   @item self-sigs-only
-  Accept only self-signatures while importing a key.  All other
-  key-signatures are skipped at an early import stage.  This option
-  can be used with @code{keyserver-options} to mitigate attempts to
-  flood a key with bogus signatures from a keyserver.  The drawback is
-  that all other valid key-signatures, as required by the Web of Trust
-  are also not imported.
+  Accept only self-signatures while importing a key.  All other key
+  signatures are skipped at an early import stage.  This option can be
+  used with @code{keyserver-options} to mitigate attempts to flood a
+  key with bogus signatures from a keyserver.  The drawback is that
+  all other valid key signatures, as required by the Web of Trust are
+  also not imported.  Note that when using this option along with
+  import-clean it suppresses the final clean step after merging the
+  imported key into the existing key.
 
   @item repair-keys
   After import, fix various problems with the
@@ -2899,7 +2913,9 @@ Write log output to file descriptor @var{n} and not to STDERR.
 @itemx --logger-file @var{file}
 @opindex log-file
 Same as @option{--logger-fd}, except the logger data is written to
-file @var{file}.  Use @file{socket://} to log to s socket.
+file @var{file}.  Use @file{socket://} to log to a socket.  Note that
+in this version of gpg the option has only an effect if
+@option{--batch} is also used.
 
 @item --attribute-fd @var{n}
 @opindex attribute-fd
@@ -3262,6 +3278,12 @@ weak.  See also @option{--allow-weak-digest-algos} to disable
 rejection of weak digests.  MD5 is always considered weak, and does
 not need to be listed explicitly.
 
+@item --allow-weak-key-signatures
+@opindex allow-weak-key-signatures
+To avoid a minor risk of collision attacks on third-party key
+signatures made using SHA-1, those key signatures are considered
+invalid.  This options allows to override this restriction.
+
 @item --no-default-keyring
 @opindex no-default-keyring
 Do not add the default keyrings to the list of keyrings. Note that
@@ -3295,7 +3317,7 @@ command has the same effect as using @option{--list-keys} with
 @option{--with-sig-list}.  Note that in contrast to
 @option{--check-signatures} the key signatures are not verified.  This
 command can be used to create a list of signing keys missing in the
-lcoal keyring; for example:
+local keyring; for example:
 
 @example
       gpg --list-sigs --with-colons USERID | \
@@ -3818,10 +3840,10 @@ the same type.  For example the four options in this example:
 
 @c man:.RS
 @example
- --import-option keep-uid="uid =~ Alfa"
- --import-option keep-uid="&& uid !~ Test"
- --import-option keep-uid="|| uid =~ Alpha"
- --import-option keep-uid="uid !~ Test"
+ --import-filter keep-uid="uid =~ Alfa"
+ --import-filter keep-uid="&& uid !~ Test"
+ --import-filter keep-uid="|| uid =~ Alpha"
+ --import-filter keep-uid="uid !~ Test"
 @end example
 @c man:.RE
 
@@ -3830,7 +3852,7 @@ which is equivalent to
 
 @c man:.RS
 @example
- --import-option \
+ --import-filter \
   keep-uid="uid =~ Alfa" && uid !~ Test" || uid =~ Alpha" && "uid !~ Test"
 @end example
 @c man:.RE
index dc5ca25..7dcd84e 100644 (file)
@@ -1564,7 +1564,7 @@ string @code{true} or @code{yes}.  The evaluation is done by passing
   /subst
   /let i 3
   /while $i
-    /echo loop couter is $i
+    /echo loop counter is $i
     /let i $@{- $i 1@}
   /end
 @end smallexample
@@ -1965,7 +1965,7 @@ Extract all files from an encrypted archive.
 
 @item --sign
 @itemx -s
-Make a signed archive from the given files and directories.  Thsi can
+Make a signed archive from the given files and directories.  This can
 be combined with option @option{--encrypt} to create a signed and then
 encrypted archive.
 
@@ -2035,7 +2035,7 @@ linefeed to separate file names.
 
 @item --openpgp
 @opindex openpgp
-This option has no effect becuase OpenPGP encryption and signing is
+This option has no effect because OpenPGP encryption and signing is
 the default.
 
 @item --cms
index 4630506..574f6ca 100644 (file)
@@ -336,7 +336,9 @@ start_agent (ctrl_t ctrl, int flag_for_card)
       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",
+        rc = assuan_transact (agent_ctx,
+                              opt.flags.use_only_openpgp_card?
+                              "SCD SERIALNO openpgp" : "SCD SERIALNO",
                               NULL, NULL, NULL, NULL,
                               learn_status_cb, &info);
       if (rc && !(flag_for_card & FLAG_FOR_CARD_SUPPRESS_ERRORS))
@@ -352,7 +354,7 @@ start_agent (ctrl_t ctrl, int flag_for_card)
               break;
             default:
               write_status_text (STATUS_CARDCTRL, "4");
-              log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc));
+              log_info ("selecting card failed: %s\n", gpg_strerror (rc));
               break;
             }
         }
@@ -706,13 +708,29 @@ learn_status_cb (void *opaque, const char *line)
     }
   else if (keywordlen == 3 && !memcmp (keyword, "KDF", 3))
     {
-      parm->kdf_do_enabled = 1;
+      unsigned char *data = unescape_status_string (line);
+
+      if (data[2] != 0x03)
+        parm->kdf_do_enabled = 0;
+      else if (data[22] != 0x85)
+        parm->kdf_do_enabled = 1;
+      else
+        parm->kdf_do_enabled = 2;
+      xfree (data);
     }
 
   return 0;
 }
 
-/* Call the scdaemon to learn about a smartcard */
+
+/* Call the scdaemon to learn about a smartcard.  Note that in
+ * contradiction to the function's name, gpg-agent's LEARN command is
+ * used and not the low-level "SCD LEARN".
+ * Used by:
+ *  card-util.c
+ *  keyedit_menu
+ *  card_store_key_with_backup  (Woth force to remove secret key data)
+ */
 int
 agent_scd_learn (struct agent_card_info_s *info, int force)
 {
@@ -745,10 +763,102 @@ agent_scd_learn (struct agent_card_info_s *info, int force)
 }
 
 
+\f
+/* Callback for the agent_scd_keypairinfo function.  */
+static gpg_error_t
+scd_keypairinfo_status_cb (void *opaque, const char *line)
+{
+  strlist_t *listaddr = opaque;
+  const char *keyword = line;
+  int keywordlen;
+  strlist_t sl;
+  char *p;
+
+  for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
+    ;
+  while (spacep (line))
+    line++;
+
+  if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen))
+    {
+      sl = append_to_strlist (listaddr, line);
+      p = sl->d;
+      /* Make sure that we only have two tokens so that future
+       * extensions of the format won't change the format expected by
+       * the caller.  */
+      while (*p && !spacep (p))
+        p++;
+      if (*p)
+        {
+          while (spacep (p))
+            p++;
+          while (*p && !spacep (p))
+            p++;
+          if (*p)
+            {
+              *p++ = 0;
+              while (spacep (p))
+                p++;
+              while (*p && !spacep (p))
+                {
+                  switch (*p++)
+                    {
+                    case 'c': sl->flags |= GCRY_PK_USAGE_CERT; break;
+                    case 's': sl->flags |= GCRY_PK_USAGE_SIGN; break;
+                    case 'e': sl->flags |= GCRY_PK_USAGE_ENCR; break;
+                    case 'a': sl->flags |= GCRY_PK_USAGE_AUTH; break;
+                    }
+                }
+            }
+        }
+    }
+
+  return 0;
+}
+
+
+/* Read the keypairinfo lines of the current card directly from
+ * scdaemon.  The list is returned as a string made up of the keygrip,
+ * a space and the keyref.  The flags of the string carry the usage
+ * bits. */
+gpg_error_t
+agent_scd_keypairinfo (ctrl_t ctrl, strlist_t *r_list)
+{
+  gpg_error_t err;
+  strlist_t list = NULL;
+  struct default_inq_parm_s inq_parm;
+
+  *r_list = NULL;
+  err= start_agent (ctrl, 1);
+  if (err)
+    return err;
+  memset (&inq_parm, 0, sizeof inq_parm);
+  inq_parm.ctx = agent_ctx;
+
+  err = assuan_transact (agent_ctx, "SCD LEARN --keypairinfo",
+                         NULL, NULL,
+                         default_inq_cb, &inq_parm,
+                         scd_keypairinfo_status_cb, &list);
+  if (!err && !list)
+    err = gpg_error (GPG_ERR_NO_DATA);
+  if (err)
+    {
+      free_strlist (list);
+      return err;
+    }
+  *r_list = list;
+  return 0;
+}
+
+
+
 /* Send an APDU to the current card.  On success the status word is
-   stored at R_SW.  With HEXAPDU being NULL only a RESET command is
-   send to scd.  With HEXAPDU being the string "undefined" the command
-   "SERIALNO undefined" is send to scd. */
+ * stored at R_SW.  With HEXAPDU being NULL only a RESET command is
+ * send to scd.  With HEXAPDU being the string "undefined" the command
+ * "SERIALNO undefined" is send to scd.
+ * Used by:
+ *  card-util.c
+ */
 gpg_error_t
 agent_scd_apdu (const char *hexapdu, unsigned int *r_sw)
 {
@@ -802,6 +912,10 @@ agent_scd_apdu (const char *hexapdu, unsigned int *r_sw)
 }
 
 
+/* Used by:
+ *  card_store_subkey
+ *  card_store_key_with_backup
+ */
 int
 agent_keytocard (const char *hexgrip, int keyno, int force,
                  const char *serialno, const char *timestamp)
@@ -828,9 +942,99 @@ agent_keytocard (const char *hexgrip, int keyno, int force,
   return rc;
 }
 \f
+/* Object used with the agent_scd_getattr_one.  */
+struct getattr_one_parm_s {
+  const char *keyword;  /* Keyword to look for.  */
+  char *data;           /* Malloced and unescaped data.  */
+  gpg_error_t err;      /* Error code or 0 on success. */
+};
+
+
+/* Callback for agent_scd_getattr_one.  */
+static gpg_error_t
+getattr_one_status_cb (void *opaque, const char *line)
+{
+  struct getattr_one_parm_s *parm = opaque;
+  const char *s;
+
+  if (parm->data)
+    return 0; /* We want only the first occurrence.  */
+
+  if ((s=has_leading_keyword (line, parm->keyword)))
+    {
+      parm->data = percent_plus_unescape (s, 0xff);
+      if (!parm->data)
+        parm->err = gpg_error_from_syserror ();
+    }
+
+  return 0;
+}
+
+
+/* Simplified version of agent_scd_getattr.  This function returns
+ * only the first occurance of the attribute NAME and stores it at
+ * R_VALUE.  A nul in the result is silennly replaced by 0xff.  On
+ * error NULL is stored at R_VALUE.  */
+gpg_error_t
+agent_scd_getattr_one (const char *name, char **r_value)
+{
+  gpg_error_t err;
+  char line[ASSUAN_LINELENGTH];
+  struct default_inq_parm_s inqparm;
+  struct getattr_one_parm_s parm;
+
+  *r_value = NULL;
+
+  if (!*name)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  memset (&inqparm, 0, sizeof inqparm);
+  inqparm.ctx = agent_ctx;
+
+  memset (&parm, 0, sizeof parm);
+  parm.keyword = name;
+
+  /* We assume that NAME does not need escaping. */
+  if (12 + strlen (name) > DIM(line)-1)
+    return gpg_error (GPG_ERR_TOO_LARGE);
+  stpcpy (stpcpy (line, "SCD GETATTR "), name);
+
+  err = start_agent (NULL, 1);
+  if (err)
+    return err;
+
+  err = assuan_transact (agent_ctx, line,
+                         NULL, NULL,
+                         default_inq_cb, &inqparm,
+                         getattr_one_status_cb, &parm);
+  if (!err && parm.err)
+    err = parm.err;
+  else if (!err && !parm.data)
+    err = gpg_error (GPG_ERR_NO_DATA);
+
+  if (!err)
+    *r_value = parm.data;
+  else
+    xfree (parm.data);
+
+  return err;
+}
+
+
+\f
 /* Call the agent to retrieve a data object.  This function returns
-   the data in the same structure as used by the learn command.  It is
-   allowed to update such a structure using this command. */
+ * the data in the same structure as used by the learn command.  It is
+ * allowed to update such a structure using this command.
+ *
+ *  Used by:
+ *     build_sk_list
+ *     enum_secret_keys
+ *     get_signature_count
+ *     card-util.c
+ *     generate_keypair (KEY-ATTR)
+ *     card_store_key_with_backup (SERIALNO)
+ *     generate_card_subkeypair  (KEY-ATTR)
+ */
 int
 agent_scd_getattr (const char *name, struct agent_card_info_s *info)
 {
@@ -859,24 +1063,23 @@ agent_scd_getattr (const char *name, struct agent_card_info_s *info)
   return rc;
 }
 
+
 \f
-/* Send an setattr command to the SCdaemon.  SERIALNO is not actually
-   used here but required by gpg 1.4's implementation of this code in
-   cardglue.c. */
-int
-agent_scd_setattr (const char *name,
-                   const unsigned char *value, size_t valuelen,
-                   const char *serialno)
+/* Send an setattr command to the SCdaemon.
+ * Used by:
+ *   card-util.c
+ */
+gpg_error_t
+agent_scd_setattr (const char *name, const void *value_arg, size_t valuelen)
 {
-  int rc;
+  gpg_error_t err;
+  const unsigned char *value = value_arg;
   char line[ASSUAN_LINELENGTH];
   char *p;
   struct default_inq_parm_s parm;
 
   memset (&parm, 0, sizeof parm);
 
-  (void)serialno;
-
   if (!*name || !valuelen)
     return gpg_error (GPG_ERR_INV_VALUE);
 
@@ -902,16 +1105,16 @@ agent_scd_setattr (const char *name,
     }
   *p = 0;
 
-  rc = start_agent (NULL, 1);
-  if (!rc)
+  err = start_agent (NULL, 1);
+  if (!err)
     {
       parm.ctx = agent_ctx;
-      rc = assuan_transact (agent_ctx, line, NULL, NULL,
+      err = assuan_transact (agent_ctx, line, NULL, NULL,
                             default_inq_cb, &parm, NULL, NULL);
     }
 
-  status_sc_op_failure (rc);
-  return rc;
+  status_sc_op_failure (err);
+  return err;
 }
 
 
@@ -937,7 +1140,10 @@ inq_writecert_parms (void *opaque, const char *line)
 }
 
 
-/* Send a WRITECERT command to the SCdaemon. */
+/* Send a WRITECERT command to the SCdaemon.
+ * Used by:
+ *  card-util.c
+ */
 int
 agent_scd_writecert (const char *certidstr,
                      const unsigned char *certdata, size_t certdatalen)
@@ -969,60 +1175,6 @@ agent_scd_writecert (const char *certidstr,
 
 
 \f
-/* Handle a KEYDATA inquiry.  Note, we only send the data,
-   assuan_transact takes care of flushing and writing the end */
-static gpg_error_t
-inq_writekey_parms (void *opaque, const char *line)
-{
-  int rc;
-  struct writekey_parm_s *parm = opaque;
-
-  if (has_leading_keyword (line, "KEYDATA"))
-    {
-      rc = assuan_send_data (parm->dflt->ctx, parm->keydata, parm->keydatalen);
-    }
-  else
-    rc = default_inq_cb (parm->dflt, line);
-
-  return rc;
-}
-
-
-/* Send a WRITEKEY command to the SCdaemon. */
-int
-agent_scd_writekey (int keyno, const char *serialno,
-                    const unsigned char *keydata, size_t keydatalen)
-{
-  int rc;
-  char line[ASSUAN_LINELENGTH];
-  struct writekey_parm_s parms;
-  struct default_inq_parm_s dfltparm;
-
-  memset (&dfltparm, 0, sizeof dfltparm);
-
-  (void)serialno;
-
-  rc = start_agent (NULL, 1);
-  if (rc)
-    return rc;
-
-  memset (&parms, 0, sizeof parms);
-
-  snprintf (line, DIM(line), "SCD WRITEKEY --force OPENPGP.%d", keyno);
-  dfltparm.ctx = agent_ctx;
-  parms.dflt = &dfltparm;
-  parms.keydata = keydata;
-  parms.keydatalen = keydatalen;
-
-  rc = assuan_transact (agent_ctx, line, NULL, NULL,
-                        inq_writekey_parms, &parms, NULL, NULL);
-
-  status_sc_op_failure (rc);
-  return rc;
-}
-
-
-\f
 /* Status callback for the SCD GENKEY command. */
 static gpg_error_t
 scd_genkey_cb (void *opaque, const char *line)
@@ -1049,10 +1201,13 @@ scd_genkey_cb (void *opaque, const char *line)
 }
 
 /* Send a GENKEY command to the SCdaemon.  If *CREATETIME is not 0,
-  the value will be passed to SCDAEMON with --timestamp option so that
-  the key is created with this.  Otherwise, timestamp was generated by
-  SCDEAMON.  On success, creation time is stored back to
-  CREATETIME.  */
+ * the value will be passed to SCDAEMON with --timestamp option so that
+ * the key is created with this.  Otherwise, timestamp was generated by
+ * SCDEAMON.  On success, creation time is stored back to
+ * CREATETIME.
+ * Used by:
+ *   gen_card_key
+ */
 int
 agent_scd_genkey (int keyno, int force, u32 *createtime)
 {
@@ -1085,9 +1240,17 @@ agent_scd_genkey (int keyno, int force, u32 *createtime)
   status_sc_op_failure (rc);
   return rc;
 }
+
+
 \f
 /* Return the serial number of the card or an appropriate error.  The
-   serial number is returned as a hexstring. */
+ * serial number is returned as a hexstring.  With DEMAND the active
+ * card is switched to the card with that serialno.
+ * Used by:
+ *   card-util.c
+ *   build_sk_list
+ *   enum_secret_keys
+ */
 int
 agent_scd_serialno (char **r_serialno, const char *demand)
 {
@@ -1095,7 +1258,7 @@ agent_scd_serialno (char **r_serialno, const char *demand)
   char *serialno = NULL;
   char line[ASSUAN_LINELENGTH];
 
-  err = start_agent (NULL, 1 | FLAG_FOR_CARD_SUPPRESS_ERRORS);
+  err = start_agent (NULL, (1 | FLAG_FOR_CARD_SUPPRESS_ERRORS));
   if (err)
     return err;
 
@@ -1116,8 +1279,13 @@ agent_scd_serialno (char **r_serialno, const char *demand)
   *r_serialno = serialno;
   return 0;
 }
+
+
 \f
-/* Send a READCERT command to the SCdaemon. */
+/* Send a READCERT command to the SCdaemon.
+ * Used by:
+ *  card-util.c
+ */
 int
 agent_scd_readcert (const char *certidstr,
                     void **r_buf, size_t *r_buflen)
@@ -1155,6 +1323,51 @@ agent_scd_readcert (const char *certidstr,
 
   return 0;
 }
+
+
+/* This is a variant of agent_readkey which sends a READKEY command
+ * directly Scdaemon.  On success a new s-expression is stored at
+ * R_RESULT.  */
+gpg_error_t
+agent_scd_readkey (const char *keyrefstr, gcry_sexp_t *r_result)
+{
+  gpg_error_t err;
+  char line[ASSUAN_LINELENGTH];
+  membuf_t data;
+  unsigned char *buf;
+  size_t len, buflen;
+  struct default_inq_parm_s dfltparm;
+
+  memset (&dfltparm, 0, sizeof dfltparm);
+  dfltparm.ctx = agent_ctx;
+
+  *r_result = NULL;
+  err = start_agent (NULL, 1);
+  if (err)
+    return err;
+
+  init_membuf (&data, 1024);
+  snprintf (line, DIM(line), "SCD READKEY %s", keyrefstr);
+  err = assuan_transact (agent_ctx, line,
+                         put_membuf_cb, &data,
+                         default_inq_cb, &dfltparm,
+                         NULL, NULL);
+  if (err)
+    {
+      xfree (get_membuf (&data, &len));
+      return err;
+    }
+  buf = get_membuf (&data, &buflen);
+  if (!buf)
+    return gpg_error_from_syserror ();
+
+  err = gcry_sexp_new (r_result, buf, buflen, 0);
+  xfree (buf);
+
+  return err;
+}
+
+
 \f
 struct card_cardlist_parm_s {
   int error;
@@ -1192,7 +1405,12 @@ card_cardlist_cb (void *opaque, const char *line)
   return 0;
 }
 
-/* Return cardlist.  */
+
+/* Return a list of currently available cards.
+ * Used by:
+ *   card-util.c
+ *   skclist.c
+ */
 int
 agent_scd_cardlist (strlist_t *result)
 {
@@ -1221,16 +1439,20 @@ agent_scd_cardlist (strlist_t *result)
 
   return 0;
 }
+
+
 \f
 /* Change the PIN of an OpenPGP card or reset the retry counter.
-   CHVNO 1: Change the PIN
-         2: For v1 cards: Same as 1.
-            For v2 cards: Reset the PIN using the Reset Code.
-         3: Change the admin PIN
-       101: Set a new PIN and reset the retry counter
-       102: For v1 cars: Same as 101.
-            For v2 cards: Set a new Reset Code.
-   SERIALNO is not used.
+ * CHVNO 1: Change the PIN
+ *       2: For v1 cards: Same as 1.
+ *          For v2 cards: Reset the PIN using the Reset Code.
+ *       3: Change the admin PIN
+ *     101: Set a new PIN and reset the retry counter
+ *     102: For v1 cars: Same as 101.
+ *          For v2 cards: Set a new Reset Code.
+ * SERIALNO is not used.
+ * Used by:
+ *  card-util.c
  */
 int
 agent_scd_change_pin (int chvno, const char *serialno)
@@ -1264,8 +1486,11 @@ agent_scd_change_pin (int chvno, const char *serialno)
 
 
 /* Perform a CHECKPIN operation.  SERIALNO should be the serial
-   number of the card - optionally followed by the fingerprint;
-   however the fingerprint is ignored here. */
+ * number of the card - optionally followed by the fingerprint;
+ * however the fingerprint is ignored here.
+ * Used by:
+ *  card-util.c
+ */
 int
 agent_scd_checkpin  (const char *serialno)
 {
@@ -1290,15 +1515,6 @@ agent_scd_checkpin  (const char *serialno)
 }
 
 
-/* Dummy function, only used by the gpg 1.4 implementation. */
-void
-agent_clear_pin_cache (const char *sn)
-{
-  (void)sn;
-}
-
-
-
 \f
 /* Note: All strings shall be UTF-8. On success the caller needs to
    free the string stored at R_PASSPHRASE. On error NULL will be
@@ -2037,25 +2253,28 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
       return err;
     }
 
-  put_membuf (&data, "", 1); /* Make sure it is 0 terminated.  */
   buf = get_membuf (&data, &len);
   if (!buf)
     return gpg_error_from_syserror ();
-  log_assert (len); /* (we forced Nul termination.)  */
 
-  if (*buf != '(')
+  if (len == 0 || *buf != '(')
     {
       xfree (buf);
       return gpg_error (GPG_ERR_INV_SEXP);
     }
 
-  if (len < 13 || memcmp (buf, "(5:value", 8) ) /* "(5:valueN:D)\0" */
+  if (len < 12 || memcmp (buf, "(5:value", 8) ) /* "(5:valueN:D)" */
     {
       xfree (buf);
       return gpg_error (GPG_ERR_INV_SEXP);
     }
-  len -= 10;   /* Count only the data of the second part. */
+  while (buf[len-1] == 0)
+    len--;
+  if (buf[len-1] != ')')
+    return gpg_error (GPG_ERR_INV_SEXP);
+  len--; /* Drop the final close-paren. */
   p = buf + 8; /* Skip leading parenthesis and the value tag. */
+  len -= 8;   /* Count only the data of the second part. */
 
   n = strtoul (p, &endp, 10);
   if (!n || *endp != ':')
index d7f102c..94ca154 100644 (file)
@@ -71,7 +71,7 @@ struct agent_card_info_s
     unsigned int kdf:1;    /* KDF object to support PIN hashing available.  */
   } extcap;
   unsigned int status_indicator;
-  int kdf_do_enabled;      /* Card has a KDF object */
+  int kdf_do_enabled;      /* Non-zero if card has a KDF object, 0 if not.  */
 };
 
 
@@ -82,6 +82,9 @@ void agent_release_card_info (struct agent_card_info_s *info);
 /* Return card info. */
 int agent_scd_learn (struct agent_card_info_s *info, int force);
 
+/* Get the keypariinfo directly from scdaemon.  */
+gpg_error_t agent_scd_keypairinfo (ctrl_t ctrl, strlist_t *r_list);
+
 /* Return list of cards.  */
 int agent_scd_cardlist (strlist_t *result);
 
@@ -91,6 +94,9 @@ int agent_scd_serialno (char **r_serialno, const char *demand);
 /* Send an APDU to the card.  */
 gpg_error_t agent_scd_apdu (const char *hexapdu, unsigned int *r_sw);
 
+/* Get attribute NAME from the card and store at R_VALUE.  */
+gpg_error_t agent_scd_getattr_one (const char *name, char **r_value);
+
 /* Update INFO with the attribute NAME. */
 int agent_scd_getattr (const char *name, struct agent_card_info_s *info);
 
@@ -99,35 +105,29 @@ int agent_keytocard (const char *hexgrip, int keyno, int force,
                      const char *serialno, const char *timestamp);
 
 /* Send a SETATTR command to the SCdaemon. */
-int agent_scd_setattr (const char *name,
-                       const unsigned char *value, size_t valuelen,
-                       const char *serialno);
+gpg_error_t agent_scd_setattr (const char *name,
+                               const void *value, size_t valuelen);
 
 /* Send a WRITECERT command to the SCdaemon. */
 int agent_scd_writecert (const char *certidstr,
                           const unsigned char *certdata, size_t certdatalen);
 
-/* Send a WRITEKEY command to the SCdaemon. */
-int agent_scd_writekey (int keyno, const char *serialno,
-                        const unsigned char *keydata, size_t keydatalen);
-
 /* Send a GENKEY command to the SCdaemon. */
 int agent_scd_genkey (int keyno, int force, u32 *createtime);
 
-/* Send a READKEY command to the SCdaemon. */
+/* Send a READCERT command to the SCdaemon. */
 int agent_scd_readcert (const char *certidstr,
                         void **r_buf, size_t *r_buflen);
 
+/* Send a READKEY command to the SCdaemon.  */
+gpg_error_t agent_scd_readkey (const char *keyrefstr, gcry_sexp_t *r_result);
+
 /* Change the PIN of an OpenPGP card or reset the retry counter. */
 int agent_scd_change_pin (int chvno, const char *serialno);
 
 /* Send the CHECKPIN command to the SCdaemon. */
 int agent_scd_checkpin  (const char *serialno);
 
-/* Dummy function, only implemented by gpg 1.4. */
-void agent_clear_pin_cache (const char *sn);
-
-
 /* Send the GET_PASSPHRASE command to the agent.  */
 gpg_error_t agent_get_passphrase (const char *cache_id,
                                   const char *err_msg,
index 8896f27..4507e71 100644 (file)
@@ -395,6 +395,7 @@ ks_status_cb (void *opaque, const char *line)
   gpg_error_t err = 0;
   const char *s, *s2;
   const char *warn;
+  int is_note = 0;
 
   if ((s = has_leading_keyword (line, parm->keyword? parm->keyword : "SOURCE")))
     {
@@ -406,18 +407,30 @@ ks_status_cb (void *opaque, const char *line)
             err = gpg_error_from_syserror ();
         }
     }
-  else if ((s = has_leading_keyword (line, "WARNING")))
+  else if ((s = has_leading_keyword (line, "WARNING"))
+           || (is_note = !!(s = has_leading_keyword (line, "NOTE"))))
     {
       if ((s2 = has_leading_keyword (s, "tor_not_running")))
         warn = _("Tor is not running");
       else if ((s2 = has_leading_keyword (s, "tor_config_problem")))
         warn = _("Tor is not properly configured");
+      else if ((s2 = has_leading_keyword (s, "dns_config_problem")))
+        warn = _("DNS is not properly configured");
+      else if ((s2 = has_leading_keyword (s, "http_redirect")))
+        warn = _("unacceptable HTTP redirect from server");
+      else if ((s2 = has_leading_keyword (s, "http_redirect_cleanup")))
+        warn = _("unacceptable HTTP redirect from server was cleaned up");
+      else if ((s2 = has_leading_keyword (s, "tls_cert_error")))
+        warn = _("server uses an invalid certificate");
       else
         warn = NULL;
 
       if (warn)
         {
-          log_info (_("WARNING: %s\n"), warn);
+          if (is_note)
+            log_info (_("Note: %s\n"), warn);
+          else
+            log_info (_("WARNING: %s\n"), warn);
           if (s2)
             {
               while (*s2 && !spacep (s2))
index 13c2445..c02811b 100644 (file)
@@ -91,8 +91,6 @@ change_pin (int unblock_v2, int allow_admin)
   log_info (_("OpenPGP card no. %s detected\n"),
               info.serialno? info.serialno : "[none]");
 
-  agent_clear_pin_cache (info.serialno);
-
   if (opt.batch)
     {
       agent_release_card_info (&info);
@@ -418,36 +416,43 @@ current_card_status (ctrl_t ctrl, estream_t fp,
   if (!info.serialno || strncmp (info.serialno, "D27600012401", 12)
       || strlen (info.serialno) != 32 )
     {
+      const char *name1, *name2;
       if (info.apptype && !strcmp (info.apptype, "NKS"))
         {
-          if (opt.with_colons)
-            es_fputs ("netkey-card:\n", fp);
-          log_info ("this is a NetKey card\n");
+          name1 = "netkey";
+          name2 = "NetKey";
         }
       else if (info.apptype && !strcmp (info.apptype, "DINSIG"))
         {
-          if (opt.with_colons)
-            es_fputs ("dinsig-card:\n", fp);
-          log_info ("this is a DINSIG compliant card\n");
+          name1 = "dinsig";
+          name2 = "DINSIG";
         }
       else if (info.apptype && !strcmp (info.apptype, "P15"))
         {
-          if (opt.with_colons)
-            es_fputs ("pkcs15-card:\n", fp);
-          log_info ("this is a PKCS#15 compliant card\n");
+          name1 = "pkcs15";
+          name2 = "PKCS#15";
         }
       else if (info.apptype && !strcmp (info.apptype, "GELDKARTE"))
         {
-          if (opt.with_colons)
-            es_fputs ("geldkarte-card:\n", fp);
-          log_info ("this is a Geldkarte compliant card\n");
+          name1 = "geldkarte";
+          name2 = "Geldkarte";
+        }
+      else if (info.apptype && !strcmp (info.apptype, "PIV"))
+        {
+          name1 = "piv";
+          name2 = "PIV";
         }
       else
         {
-          if (opt.with_colons)
-            es_fputs ("unknown:\n", fp);
+          name1 = "unknown";
+          name2 = "Unknown";
         }
-      log_info ("not an OpenPGP card\n");
+
+      if (opt.with_colons)
+        es_fprintf (fp, "%s-card:\n", name1);
+      else
+        tty_fprintf (fp, "Application type .: %s\n", name2);
+
       agent_release_card_info (&info);
       xfree (pk);
       return;
@@ -462,6 +467,8 @@ current_card_status (ctrl_t ctrl, estream_t fp,
 
   if (opt.with_colons)
     es_fputs ("openpgp-card:\n", fp);
+  else
+    tty_fprintf (fp, "Application type .: %s\n", "OpenPGP");
 
 
   if (opt.with_colons)
@@ -511,7 +518,16 @@ current_card_status (ctrl_t ctrl, estream_t fp,
       es_fprintf (fp, "sigcount:%lu:::\n", info.sig_counter);
       if (info.extcap.kdf)
         {
-          es_fprintf (fp, "kdf:%s:\n", info.kdf_do_enabled ? "on" : "off");
+          const char *setup;
+
+          if (info.kdf_do_enabled == 0)
+            setup = "off";
+          else if (info.kdf_do_enabled == 1)
+            setup = "single";
+          else
+            setup = "on";
+
+          es_fprintf (fp, "kdf:%s:\n", setup);
         }
 
       for (i=0; i < 4; i++)
@@ -558,9 +574,9 @@ current_card_status (ctrl_t ctrl, estream_t fp,
 
       print_isoname (fp, "Name of cardholder: ", "name", info.disp_name);
       print_name (fp, "Language prefs ...: ", info.disp_lang);
-      tty_fprintf (fp,    "Sex ..............: %s\n",
-                   info.disp_sex == 1? _("male"):
-                   info.disp_sex == 2? _("female") : _("unspecified"));
+      tty_fprintf (fp, "Salutation .......: %s\n",
+                   info.disp_sex == 1? _("Mr."):
+                   info.disp_sex == 2? _("Ms.") : "");
       print_name (fp, "URL of public key : ", info.pubkey_url);
       print_name (fp, "Login data .......: ", info.login_data);
       if (info.private_do[0])
@@ -618,8 +634,16 @@ current_card_status (ctrl_t ctrl, estream_t fp,
       tty_fprintf (fp,    "Signature counter : %lu\n", info.sig_counter);
       if (info.extcap.kdf)
         {
-          tty_fprintf (fp, "KDF setting ......: %s\n",
-                       info.kdf_do_enabled ? "on" : "off");
+          const char *setup;
+
+          if (info.kdf_do_enabled == 0)
+            setup = "off";
+          else if (info.kdf_do_enabled == 1)
+            setup = "single";
+          else
+            setup = "on";
+
+          tty_fprintf (fp, "KDF setting ......: %s\n", setup);
         }
       tty_fprintf (fp, "Signature key ....:");
       print_sha1_fpr (fp, info.fpr1valid? info.fpr1:NULL);
@@ -678,6 +702,7 @@ card_status (ctrl_t ctrl, estream_t fp, const char *serialno)
   strlist_t card_list, sl;
   char *serialno0, *serialno1;
   int all_cards = 0;
+  int any_card = 0;
 
   if (serialno == NULL)
     {
@@ -705,6 +730,10 @@ card_status (ctrl_t ctrl, estream_t fp, const char *serialno)
       if (!all_cards && strcmp (serialno, sl->d))
         continue;
 
+      if (any_card && !opt.with_colons)
+        tty_fprintf (fp, "\n");
+      any_card = 1;
+
       err = agent_scd_serialno (&serialno1, sl->d);
       if (err)
         {
@@ -797,7 +826,7 @@ change_name (void)
       return -1;
     }
 
-  rc = agent_scd_setattr ("DISP-NAME", isoname, strlen (isoname), NULL );
+  rc = agent_scd_setattr ("DISP-NAME", isoname, strlen (isoname));
   if (rc)
     log_error ("error setting Name: %s\n", gpg_strerror (rc));
 
@@ -818,7 +847,7 @@ change_url (void)
   trim_spaces (url);
   cpr_kill_prompt ();
 
-  rc = agent_scd_setattr ("PUBKEY-URL", url, strlen (url), NULL );
+  rc = agent_scd_setattr ("PUBKEY-URL", url, strlen (url));
   if (rc)
     log_error ("error setting URL: %s\n", gpg_strerror (rc));
   xfree (url);
@@ -974,7 +1003,7 @@ change_login (const char *args)
       n = strlen (data);
     }
 
-  rc = agent_scd_setattr ("LOGIN-DATA", data, n, NULL );
+  rc = agent_scd_setattr ("LOGIN-DATA", data, n);
   if (rc)
     log_error ("error setting login data: %s\n", gpg_strerror (rc));
   xfree (data);
@@ -1012,7 +1041,7 @@ change_private_do (const char *args, int nr)
       n = strlen (data);
     }
 
-  rc = agent_scd_setattr (do_name, data, n, NULL );
+  rc = agent_scd_setattr (do_name, data, n);
   if (rc)
     log_error ("error setting private DO: %s\n", gpg_strerror (rc));
   xfree (data);
@@ -1111,7 +1140,7 @@ change_lang (void)
       return -1;
     }
 
-  rc = agent_scd_setattr ("DISP-LANG", data, strlen (data), NULL );
+  rc = agent_scd_setattr ("DISP-LANG", data, strlen (data));
   if (rc)
     log_error ("error setting lang: %s\n", gpg_strerror (rc));
   xfree (data);
@@ -1128,7 +1157,7 @@ change_sex (void)
   int rc;
 
   data = cpr_get ("cardedit.change_sex",
-                  _("Sex ((M)ale, (F)emale or space): "));
+                  _("Salutation (M = Mr., F = Ms., or space): "));
   if (!data)
     return -1;
   trim_spaces (data);
@@ -1147,9 +1176,9 @@ change_sex (void)
       return -1;
     }
 
-  rc = agent_scd_setattr ("DISP-SEX", str, 1, NULL );
+  rc = agent_scd_setattr ("DISP-SEX", str, 1);
   if (rc)
-    log_error ("error setting sex: %s\n", gpg_strerror (rc));
+    log_error ("error setting salutation: %s\n", gpg_strerror (rc));
   xfree (data);
   write_sc_op_status (rc);
   return rc;
@@ -1193,7 +1222,7 @@ change_cafpr (int fprno)
 
   rc = agent_scd_setattr (fprno==1?"CA-FPR-1":
                           fprno==2?"CA-FPR-2":
-                          fprno==3?"CA-FPR-3":"x", fpr, 20, NULL );
+                          fprno==3?"CA-FPR-3":"x", fpr, 20);
   if (rc)
     log_error ("error setting cafpr: %s\n", gpg_strerror (rc));
   write_sc_op_status (rc);
@@ -1219,7 +1248,7 @@ toggle_forcesig (void)
   newstate = !info.chv1_cached;
   agent_release_card_info (&info);
 
-  rc = agent_scd_setattr ("CHV-STATUS-1", newstate? "\x01":"", 1, NULL);
+  rc = agent_scd_setattr ("CHV-STATUS-1", newstate? "\x01":"", 1);
   if (rc)
     log_error ("error toggling signature PIN flag: %s\n", gpg_strerror (rc));
   write_sc_op_status (rc);
@@ -1262,14 +1291,12 @@ check_pin_for_key_operation (struct agent_card_info_s *info, int *forced_chv1)
 {
   int rc = 0;
 
-  agent_clear_pin_cache (info->serialno);
-
   *forced_chv1 = !info->chv1_cached;
   if (*forced_chv1)
     { /* Switch off the forced mode so that during key generation we
          don't get bothered with PIN queries for each
          self-signature. */
-      rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1, info->serialno);
+      rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1);
       if (rc)
         {
           log_error ("error clearing forced signature PIN flag: %s\n",
@@ -1300,7 +1327,7 @@ restore_forced_chv1 (int *forced_chv1)
 
   if (*forced_chv1)
     { /* Switch back to forced state. */
-      rc = agent_scd_setattr ("CHV-STATUS-1", "", 1, NULL);
+      rc = agent_scd_setattr ("CHV-STATUS-1", "", 1);
       if (rc)
         {
           log_error ("error setting forced signature PIN flag: %s\n",
@@ -1548,7 +1575,7 @@ do_change_keyattr (int keyno, const struct key_attr *key_attr)
       return gpg_error (GPG_ERR_PUBKEY_ALGO);
     }
 
-  err = agent_scd_setattr ("KEY-ATTR", args, strlen (args), NULL);
+  err = agent_scd_setattr ("KEY-ATTR", args, strlen (args));
   if (err)
     log_error (_("error changing key attribute for key %d: %s\n"),
                keyno+1, gpg_strerror (err));
@@ -2094,8 +2121,7 @@ kdf_setup (const char *args)
     goto leave_error;
 
   err = agent_scd_setattr ("KDF", kdf_data,
-                           single ? KDF_DATA_LENGTH_MIN : KDF_DATA_LENGTH_MAX,
-                           NULL);
+                           single ? KDF_DATA_LENGTH_MIN : KDF_DATA_LENGTH_MAX);
   if (err)
     goto leave_error;
 
@@ -2108,6 +2134,8 @@ kdf_setup (const char *args)
  leave:
   agent_release_card_info (&info);
 }
+
+
 \f
 /* Data used by the command parser.  This needs to be outside of the
    function scope to allow readline based command completion.  */
@@ -2143,7 +2171,8 @@ static struct
     { "fetch"   , cmdFETCH , 0, N_("fetch the key specified in the card URL")},
     { "login"   , cmdLOGIN , 1, N_("change the login name")},
     { "lang"    , cmdLANG  , 1, N_("change the language preferences")},
-    { "sex"     , cmdSEX   , 1, N_("change card holder's sex")},
+    { "salutation",cmdSEX  , 1, N_("change card holder's salutation")},
+    { "sex"       ,cmdSEX  , 1, NULL },  /* Backward compatibility.  */
     { "cafpr"   , cmdCAFPR , 1, N_("change a CA fingerprint")},
     { "forcesig", cmdFORCESIG, 1, N_("toggle the signature force PIN flag")},
     { "generate", cmdGENERATE, 1, N_("generate new keys")},
index e91acb0..6116d74 100644 (file)
@@ -281,25 +281,16 @@ do_delete_key (ctrl_t ctrl, const char *username, int secret, int force,
        }
       else if (thiskeyonly == 2)
         {
-          int selected = 0;
-
           /* Delete the specified public subkey.  */
           for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); )
-            {
-              if (thiskeyonly && targetnode != node)
-                continue;
+            if (targetnode == node)
+              break;
+          log_assert (node);
+          delete_kbnode (node);
+          while ((node = walk_kbnode (keyblock, &kbctx, 0))
+                 && node->pkt->pkttype == PKT_SIGNATURE)
+            delete_kbnode (node);
 
-              if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
-                {
-                  selected = targetnode == node;
-                  if (selected)
-                    delete_kbnode (node);
-                }
-              else if (selected && node->pkt->pkttype == PKT_SIGNATURE)
-                delete_kbnode (node);
-              else
-                selected = 0;
-            }
           commit_kbnode (&keyblock);
           err = keydb_update_keyblock (ctrl, hd, keyblock);
           if (err)
index 08ad972..6635b5b 100644 (file)
@@ -1340,7 +1340,7 @@ subkey_is_ok (const PKT_public_key *sub)
 
 /* Return true if KEYBLOCK has only expired encryption subkyes.  Note
  * that the function returns false if the key has no encryption
- * subkeys at all or the subkecys are revoked.  */
+ * subkeys at all or the subkeys are revoked.  */
 static int
 only_expired_enc_subkeys (kbnode_t keyblock)
 {
@@ -1572,7 +1572,10 @@ get_best_pubkey_byname (ctrl_t ctrl, enum get_pubkey_modes mode,
             }
 
           if (pk)
-            *pk = best.key;
+            {
+              release_public_key_parts (pk);
+              *pk = best.key;
+            }
           else
             release_public_key_parts (&best.key);
         }
@@ -3774,180 +3777,6 @@ lookup (ctrl_t ctrl, getkey_ctx_t ctx, int want_secret,
 }
 
 
-/* Enumerate some secret keys (specifically, those specified with
- * --default-key and --try-secret-key).  Use the following procedure:
- *
- *  1) Initialize a void pointer to NULL
- *  2) Pass a reference to this pointer to this function (content)
- *     and provide space for the secret key (sk)
- *  3) Call this function as long as it does not return an error (or
- *     until you are done).  The error code GPG_ERR_EOF indicates the
- *     end of the listing.
- *  4) Call this function a last time with SK set to NULL,
- *     so that can free it's context.
- *
- * In pseudo-code:
- *
- *   void *ctx = NULL;
- *   PKT_public_key *sk = xmalloc_clear (sizeof (*sk));
- *
- *   while ((err = enum_secret_keys (&ctx, sk)))
- *     { // Process SK.
- *       if (done)
- *         break;
- *       free_public_key (sk);
- *       sk = xmalloc_clear (sizeof (*sk));
- *     }
- *
- *   // Release any resources used by CTX.
- *   enum_secret_keys (&ctx, NULL);
- *   free_public_key (sk);
- *
- *   if (gpg_err_code (err) != GPG_ERR_EOF)
- *     ; // An error occurred.
- */
-gpg_error_t
-enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk)
-{
-  gpg_error_t err = 0;
-  const char *name;
-  kbnode_t keyblock;
-  struct
-  {
-    int eof;
-    int state;
-    strlist_t sl;
-    kbnode_t keyblock;
-    kbnode_t node;
-    getkey_ctx_t ctx;
-  } *c = *context;
-
-  if (!c)
-    {
-      /* Make a new context.  */
-      c = xtrycalloc (1, sizeof *c);
-      if (!c)
-        return gpg_error_from_syserror ();
-      *context = c;
-    }
-
-  if (!sk)
-    {
-      /* Free the context.  */
-      release_kbnode (c->keyblock);
-      getkey_end (ctrl, c->ctx);
-      xfree (c);
-      *context = NULL;
-      return 0;
-    }
-
-  if (c->eof)
-    return gpg_error (GPG_ERR_EOF);
-
-  for (;;)
-    {
-      /* Loop until we have a keyblock.  */
-      while (!c->keyblock)
-        {
-          /* Loop over the list of secret keys.  */
-          do
-            {
-              name = NULL;
-              keyblock = NULL;
-              switch (c->state)
-                {
-                case 0: /* First try to use the --default-key.  */
-                  name = parse_def_secret_key (ctrl);
-                  c->state = 1;
-                  break;
-
-                case 1: /* Init list of keys to try.  */
-                  c->sl = opt.secret_keys_to_try;
-                  c->state++;
-                  break;
-
-                case 2: /* Get next item from list.  */
-                  if (c->sl)
-                    {
-                      name = c->sl->d;
-                      c->sl = c->sl->next;
-                    }
-                  else
-                    c->state++;
-                  break;
-
-                case 3: /* Init search context to enum all secret keys.  */
-                  err = getkey_bynames (ctrl, &c->ctx, NULL, NULL, 1,
-                                        &keyblock);
-                  if (err)
-                    {
-                      release_kbnode (keyblock);
-                      keyblock = NULL;
-                      getkey_end (ctrl, c->ctx);
-                      c->ctx = NULL;
-                    }
-                  c->state++;
-                  break;
-
-                case 4: /* Get next item from the context.  */
-                  if (c->ctx)
-                    {
-                      err = getkey_next (ctrl, c->ctx, NULL, &keyblock);
-                      if (err)
-                        {
-                          release_kbnode (keyblock);
-                          keyblock = NULL;
-                          getkey_end (ctrl, c->ctx);
-                          c->ctx = NULL;
-                        }
-                    }
-                  else
-                    c->state++;
-                  break;
-
-                default: /* No more names to check - stop.  */
-                  c->eof = 1;
-                  return gpg_error (GPG_ERR_EOF);
-                }
-            }
-          while ((!name || !*name) && !keyblock);
-
-          if (keyblock)
-            c->node = c->keyblock = keyblock;
-          else
-            {
-              err = getkey_byname (ctrl, NULL, NULL, name, 1, &c->keyblock);
-              if (err)
-                {
-                  /* getkey_byname might return a keyblock even in the
-                     error case - I have not checked.  Thus better release
-                     it.  */
-                  release_kbnode (c->keyblock);
-                  c->keyblock = NULL;
-                }
-              else
-                c->node = c->keyblock;
-            }
-        }
-
-      /* Get the next key from the current keyblock.  */
-      for (; c->node; c->node = c->node->next)
-       {
-         if (c->node->pkt->pkttype == PKT_PUBLIC_KEY
-              || c->node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
-           {
-             copy_public_key (sk, c->node->pkt->pkt.public_key);
-             c->node = c->node->next;
-             return 0; /* Found.  */
-           }
-        }
-
-      /* Dispose the keyblock and continue.  */
-      release_kbnode (c->keyblock);
-      c->keyblock = NULL;
-    }
-}
-
 gpg_error_t
 get_seckey_default_or_card (ctrl_t ctrl, PKT_public_key *pk,
                             const byte *fpr_card, size_t fpr_len)
@@ -4196,6 +4025,26 @@ release_akl (void)
     }
 }
 
+
+/* Returns true if the AKL is empty or has only the local method
+ * active.  */
+int
+akl_empty_or_only_local (void)
+{
+  struct akl *akl;
+  int any = 0;
+
+  for (akl = opt.auto_key_locate; akl; akl = akl->next)
+    if (akl->type != AKL_NODEFAULT && akl->type != AKL_LOCAL)
+      {
+        any = 1;
+        break;
+      }
+
+  return !any;
+}
+
+
 /* Returns false on error. */
 int
 parse_auto_key_locate (const char *options_arg)
index 2c784d4..55165ec 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -407,6 +407,7 @@ enum cmd_and_opt_values
     oAllowMultipleMessages,
     oNoAllowMultipleMessages,
     oAllowWeakDigestAlgos,
+    oAllowWeakKeySignatures,
     oFakedSystemTime,
     oNoAutostart,
     oPrintPKARecords,
@@ -422,6 +423,7 @@ enum cmd_and_opt_values
     oKeyOrigin,
     oRequestOrigin,
     oNoSymkeyCache,
+    oUseOnlyOpenPGPCard,
 
     oNoop
   };
@@ -701,7 +703,7 @@ static ARGPARSE_OPTS opts[] = {
               "delete-secret-and-public-keys", "@"),
   ARGPARSE_c (aRebuildKeydbCaches, "rebuild-keydb-caches", "@"),
 
-  ARGPARSE_s_s (oPassphrase,      "passphrase", "@"),
+  ARGPARSE_o_s (oPassphrase,      "passphrase", "@"),
   ARGPARSE_s_i (oPassphraseFD,    "passphrase-fd", "@"),
   ARGPARSE_s_s (oPassphraseFile,  "passphrase-file", "@"),
   ARGPARSE_s_i (oPassphraseRepeat,"passphrase-repeat", "@"),
@@ -887,6 +889,13 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oNoAutostart, "no-autostart", "@"),
   ARGPARSE_s_n (oNoSymkeyCache, "no-symkey-cache", "@"),
 
+  /* Options to override new security defaults.  */
+  ARGPARSE_s_n (oAllowWeakKeySignatures, "allow-weak-key-signatures", "@"),
+
+  /* Options which can be used in special circumstances. They are not
+   * published and we hope they are never required.  */
+  ARGPARSE_s_n (oUseOnlyOpenPGPCard, "use-only-openpgp-card", "@"),
+
   /* Dummy options with warnings.  */
   ARGPARSE_s_n (oUseAgent,      "use-agent", "@"),
   ARGPARSE_s_n (oNoUseAgent, "no-use-agent", "@"),
@@ -945,6 +954,9 @@ static struct debug_flags_s debug_flags [] =
 #define ALWAYS_ADD_KEYRINGS 0
 #endif
 
+/* The list of the default AKL methods.  */
+#define DEFAULT_AKL_LIST "local,wkd"
+
 
 int g10_errors_seen = 0;
 
@@ -2479,7 +2491,7 @@ main (int argc, char **argv)
 
     /* Set default options which require that malloc stuff is ready.  */
     additional_weak_digest ("MD5");
-    parse_auto_key_locate ("local,wkd");
+    parse_auto_key_locate (DEFAULT_AKL_LIST);
 
     /* Try for a version specific config file first */
     default_configname = get_default_configname ();
@@ -3095,7 +3107,7 @@ main (int argc, char **argv)
          case oBZ2CompressLevel: opt.bz2_compress_level = pargs.r.ret_int; break;
          case oBZ2DecompressLowmem: opt.bz2_decompress_lowmem=1; break;
          case oPassphrase:
-           set_passphrase_from_string(pargs.r.ret_str);
+            set_passphrase_from_string (pargs.r_type ? pargs.r.ret_str : "");
            break;
          case oPassphraseFD:
             pwfd = translate_sys2libc_fd_int (pargs.r.ret_int, 0);
@@ -3550,6 +3562,10 @@ main (int argc, char **argv)
             opt.flags.allow_weak_digest_algos = 1;
             break;
 
+          case oAllowWeakKeySignatures:
+            opt.flags.allow_weak_key_signatures = 1;
+            break;
+
           case oFakedSystemTime:
             {
               size_t len = strlen (pargs.r.ret_str);
@@ -3576,6 +3592,10 @@ main (int argc, char **argv)
             opt.def_new_key_algo = pargs.r.ret_str;
             break;
 
+          case oUseOnlyOpenPGPCard:
+            opt.flags.use_only_openpgp_card = 1;
+            break;
+
          case oNoop: break;
 
          default:
@@ -4435,7 +4455,17 @@ main (int argc, char **argv)
        sl = NULL;
        for (; argc; argc--, argv++)
           add_to_strlist2( &sl, *argv, utf8_strings );
+        if (cmd == aLocateExtKeys && akl_empty_or_only_local ())
+          {
+            /* This is a kludge to let --locate-external-keys even
+             * work if the config file has --no-auto-key-locate.  This
+             * better matches the expectations of the user.  */
+            release_akl ();
+            parse_auto_key_locate (DEFAULT_AKL_LIST);
+          }
        public_key_list (ctrl, sl, 1, cmd == aLocateExtKeys);
+
+
        free_strlist (sl);
        break;
 
index 5d3162c..95d419a 100644 (file)
@@ -853,6 +853,7 @@ read_block( IOBUF a, unsigned int options,
   struct parse_packet_ctx_s parsectx;
   PACKET *pkt;
   kbnode_t root = NULL;
+  kbnode_t lastnode = NULL;
   int in_cert, in_v3key, skip_sigs;
   u32 keyid[2];
   int got_keyid = 0;
@@ -862,7 +863,7 @@ read_block( IOBUF a, unsigned int options,
 
   if (*pending_pkt)
     {
-      root = new_kbnode( *pending_pkt );
+      root = lastnode = new_kbnode( *pending_pkt );
       *pending_pkt = NULL;
       log_assert (root->pkt->pkttype == PKT_PUBLIC_KEY
                   || root->pkt->pkttype == PKT_SECRET_KEY);
@@ -1032,9 +1033,12 @@ read_block( IOBUF a, unsigned int options,
           if (in_cert && valid_keyblock_packet (pkt->pkttype))
             {
               if (!root )
-                root = new_kbnode (pkt);
+                root = lastnode = new_kbnode (pkt);
               else
-                add_kbnode (root, new_kbnode (pkt));
+                {
+                  lastnode->next = new_kbnode (pkt);
+                  lastnode = lastnode->next;
+                }
               pkt = xmalloc (sizeof *pkt);
             }
           else
@@ -2111,7 +2115,10 @@ import_one_real (ctrl_t ctrl,
       if (err)
         goto leave;
 
-      if ((options & IMPORT_CLEAN))
+      /* Clean the final keyblock again if requested.  we can't do
+       * this if only self-signatures are imported; see bug #4628.  */
+      if ((options & IMPORT_CLEAN)
+          && !(options & IMPORT_SELF_SIGS_ONLY))
         {
           merge_keys_and_selfsig (ctrl, keyblock_orig);
           clean_all_uids (ctrl, keyblock_orig, opt.verbose,
@@ -2627,6 +2634,7 @@ sec_to_pub_keyblock (kbnode_t sec_keyblock)
   kbnode_t pub_keyblock = NULL;
   kbnode_t ctx = NULL;
   kbnode_t secnode, pubnode;
+  kbnode_t lastnode = NULL;
   unsigned int tag = 0;
 
   /* Set a tag to all nodes.  */
@@ -2666,9 +2674,12 @@ sec_to_pub_keyblock (kbnode_t sec_keyblock)
       pubnode->tag = secnode->tag;
 
       if (!pub_keyblock)
-       pub_keyblock = pubnode;
+        pub_keyblock = lastnode = pubnode;
       else
-       add_kbnode (pub_keyblock, pubnode);
+        {
+          lastnode->next = pubnode;
+          lastnode = pubnode;
+        }
     }
 
   return pub_keyblock;
index 670a8a1..45b3c85 100644 (file)
@@ -812,14 +812,27 @@ keydb_add_resource (const char *url, unsigned int flags)
               err = gpg_error (GPG_ERR_RESOURCE_LIMIT);
             else
               {
+                KEYBOX_HANDLE kbxhd;
+
                 if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY))
                   primary_keydb = token;
                 all_resources[used_resources].type = rt;
                 all_resources[used_resources].u.kb = NULL; /* Not used here */
                 all_resources[used_resources].token = token;
 
-                /* FIXME: Do a compress run if needed and no other
-                   user is currently using the keybox. */
+                /* Do a compress run if needed and no other user is
+                 * currently using the keybox. */
+                kbxhd = keybox_new_openpgp (token, 0);
+                if (kbxhd)
+                  {
+                    if (!keybox_lock (kbxhd, 1, 0))
+                      {
+                        keybox_compress (kbxhd);
+                        keybox_lock (kbxhd, 0, 0);
+                      }
+
+                    keybox_release (kbxhd);
+                  }
 
                 used_resources++;
               }
@@ -1083,7 +1096,7 @@ lock_all (KEYDB_HANDLE hd)
           rc = keyring_lock (hd->active[i].u.kr, 1);
           break;
         case KEYDB_RESOURCE_TYPE_KEYBOX:
-          rc = keybox_lock (hd->active[i].u.kb, 1);
+          rc = keybox_lock (hd->active[i].u.kb, 1, -1);
           break;
         }
     }
@@ -1101,7 +1114,7 @@ lock_all (KEYDB_HANDLE hd)
               keyring_lock (hd->active[i].u.kr, 0);
               break;
             case KEYDB_RESOURCE_TYPE_KEYBOX:
-              keybox_lock (hd->active[i].u.kb, 0);
+              keybox_lock (hd->active[i].u.kb, 0, 0);
               break;
             }
         }
@@ -1134,7 +1147,7 @@ unlock_all (KEYDB_HANDLE hd)
           keyring_lock (hd->active[i].u.kr, 0);
           break;
         case KEYDB_RESOURCE_TYPE_KEYBOX:
-          keybox_lock (hd->active[i].u.kb, 0);
+          keybox_lock (hd->active[i].u.kb, 0, 0);
           break;
         }
     }
index a0ac12f..8d956b2 100644 (file)
@@ -449,6 +449,7 @@ char *get_user_id_byfpr (ctrl_t ctrl, const byte *fpr, size_t *rn);
 char *get_user_id_byfpr_native (ctrl_t ctrl, const byte *fpr);
 
 void release_akl(void);
+int akl_empty_or_only_local (void);
 int parse_auto_key_locate(const char *options);
 int parse_key_origin (char *string);
 const char *key_origin_string (int origin);
index 6042226..c4cfe00 100644 (file)
@@ -142,7 +142,8 @@ static gpg_error_t parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
                                      const char *expirestr,
                                      int *r_algo, unsigned int *r_usage,
                                      u32 *r_expire, unsigned int *r_nbits,
-                                     const char **r_curve);
+                                     const char **r_curve,
+                                     char **r_keygrip);
 static void do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
                                  struct output_control_s *outctrl, int card );
 static int write_keyblock (iobuf_t out, kbnode_t node);
@@ -1734,24 +1735,26 @@ print_key_flags(int flags)
 
 
 /* Ask for the key flags and return them.  CURRENT gives the current
- * usage which should normally be given as 0. */
+ * usage which should normally be given as 0.  MASK gives the allowed
+ * flags.  */
 unsigned int
-ask_key_flags (int algo, int subkey, unsigned int current)
+ask_key_flags_with_mask (int algo, int subkey, unsigned int current,
+                         unsigned int mask)
 {
   /* TRANSLATORS: Please use only plain ASCII characters for the
-     translation.  If this is not possible use single digits.  The
-     string needs to 8 bytes long. Here is a description of the
-     functions:
-
-       s = Toggle signing capability
-       e = Toggle encryption capability
-       a = Toggle authentication capability
-       q = Finish
-  */
+   * translation.  If this is not possible use single digits.  The
+   * string needs to 8 bytes long. Here is a description of the
+   * functions:
+   *
+   *   s = Toggle signing capability
+   *   e = Toggle encryption capability
+   *   a = Toggle authentication capability
+   *   q = Finish
+   */
   const char *togglers = _("SsEeAaQq");
   char *answer = NULL;
   const char *s;
-  unsigned int possible = openpgp_pk_algo_usage(algo);
+  unsigned int possible;
 
   if ( strlen(togglers) != 8 )
     {
@@ -1760,19 +1763,23 @@ ask_key_flags (int algo, int subkey, unsigned int current)
       togglers = "11223300";
     }
 
-  /* Only primary keys may certify. */
-  if(subkey)
-    possible&=~PUBKEY_USAGE_CERT;
+  /* Mask the possible usage flags.  This is for example used for a
+   * card based key.  */
+  possible = (openpgp_pk_algo_usage (algo) & mask);
 
-  /* Preload the current set with the possible set, minus
-     authentication if CURRENT has been given as 0.  If CURRENT has
-     been has non-zero we mask with all possible usages. */
+  /* However, only primary keys may certify. */
+  if (subkey)
+    possible &= ~PUBKEY_USAGE_CERT;
+
+  /* Preload the current set with the possible set, without
+   * authentication if CURRENT is 0.  If CURRENT is non-zero we mask
+   * with all possible usages.  */
   if (current)
     current &= possible;
   else
     current = (possible&~PUBKEY_USAGE_AUTH);
 
-  for(;;)
+  for (;;)
     {
       tty_printf("\n");
       tty_printf(_("Possible actions for a %s key: "),
@@ -1862,6 +1869,13 @@ ask_key_flags (int algo, int subkey, unsigned int current)
 }
 
 
+unsigned int
+ask_key_flags (int algo, int subkey, unsigned int current)
+{
+  return ask_key_flags_with_mask (algo, subkey, current, ~0);
+}
+
+
 /* Check whether we have a key for the key with HEXGRIP.  Returns 0 if
    there is no such key or the OpenPGP algo number for the key.  */
 static int
@@ -1900,10 +1914,12 @@ static int
 ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
           char **r_keygrip)
 {
+  gpg_error_t err;
   char *keygrip = NULL;
   char *answer = NULL;
   int algo;
   int dummy_algo;
+  char *p;
 
   if (!r_subkey_algo)
     r_subkey_algo = &dummy_algo;
@@ -1954,6 +1970,8 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
 
   if (opt.expert && r_keygrip)
     tty_printf (_("  (%d) Existing key\n"), 13 );
+  if (r_keygrip)
+    tty_printf (_("  (%d) Existing key from card\n"), 14 );
 
   for (;;)
     {
@@ -2074,9 +2092,134 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
           *r_usage = ask_key_flags (algo, addmode, 0);
           break;
        }
+      else if ((algo == 14 || !strcmp (answer, "cardkey")) && r_keygrip)
+        {
+          char *serialno;
+          strlist_t keypairlist, sl;
+          int count, selection;
+
+          err = agent_scd_serialno (&serialno, NULL);
+          if (err)
+            {
+              tty_printf (_("error reading the card: %s\n"),
+                          gpg_strerror (err));
+              goto ask_again;
+            }
+          tty_printf (_("Serial number of the card: %s\n"), serialno);
+          xfree (serialno);
+
+          err = agent_scd_keypairinfo (ctrl, &keypairlist);
+          if (err)
+            {
+              tty_printf (_("error reading the card: %s\n"),
+                          gpg_strerror (err));
+              goto ask_again;
+            }
+
+          do
+            {
+              tty_printf (_("Available keys:\n"));
+              for (count=1,sl=keypairlist; sl; sl = sl->next, count++)
+                {
+                  gcry_sexp_t s_pkey;
+                  char *algostr = NULL;
+                  enum gcry_pk_algos algoid = 0;
+                  const char *keyref;
+                  int any = 0;
+
+                  keyref = strchr (sl->d, ' ');
+                  if (keyref)
+                    {
+                      keyref++;
+                      if (!agent_scd_readkey (keyref, &s_pkey))
+                        {
+                          algostr = pubkey_algo_string (s_pkey, &algoid);
+                          gcry_sexp_release (s_pkey);
+                        }
+                    }
+                  /* We use the flags also encode the algo for use
+                   * below.  We need to tweak the algo in case
+                   * GCRY_PK_ECC is returned becuase pubkey_algo_string
+                   * is not aware of the OpenPGP algo mapping.
+                   * FIXME: This is an ugly hack. */
+                  sl->flags &= 0xff;
+                  if (algoid == GCRY_PK_ECC
+                      && algostr && !strncmp (algostr, "nistp", 5)
+                      && !(sl->flags & GCRY_PK_USAGE_ENCR))
+                    sl->flags |= (PUBKEY_ALGO_ECDSA << 8);
+                  else if (algoid == GCRY_PK_ECC
+                           && algostr && !strcmp (algostr, "ed25519")
+                           && !(sl->flags & GCRY_PK_USAGE_ENCR))
+                    sl->flags = (PUBKEY_ALGO_EDDSA << 8);
+                  else
+                    sl->flags |= (map_pk_gcry_to_openpgp (algoid) << 8);
+
+                  tty_printf ("   (%d) %s %s", count, sl->d, algostr);
+                  if ((sl->flags & GCRY_PK_USAGE_CERT))
+                    {
+                      tty_printf ("%scert", any?",":" (");
+                      any = 1;
+                    }
+                  if ((sl->flags & GCRY_PK_USAGE_SIGN))
+                    {
+                      tty_printf ("%ssign", any?",":" (");
+                      any = 1;
+                    }
+                  if ((sl->flags & GCRY_PK_USAGE_AUTH))
+                    {
+                      tty_printf ("%sauth", any?",":" (");
+                      any = 1;
+                    }
+                  if ((sl->flags & GCRY_PK_USAGE_ENCR))
+                    {
+                      tty_printf ("%sencr", any?",":" (");
+                      any = 1;
+                    }
+                  tty_printf ("%s\n", any?")":"");
+                  xfree (algostr);
+                }
+
+              xfree (answer);
+              answer = cpr_get ("keygen.cardkey", _("Your selection? "));
+              cpr_kill_prompt ();
+              trim_spaces (answer);
+              selection = atoi (answer);
+            }
+          while (!(selection > 0 && selection < count));
+
+          for (count=1,sl=keypairlist; sl; sl = sl->next, count++)
+            if (count == selection)
+              break;
+          if (!sl)
+            {
+              /* Just in case COUNT is zero (no keys).  */
+              free_strlist (keypairlist);
+              goto ask_again;
+            }
+
+          xfree (keygrip);
+          keygrip = xstrdup (sl->d);
+          if ((p = strchr (keygrip, ' ')))
+            *p = 0;
+          algo = (sl->flags >>8);
+          if (opt.expert)
+            *r_usage = ask_key_flags_with_mask (algo, addmode,
+                                                (sl->flags & 0xff),
+                                                (sl->flags & 0xff));
+          else
+            {
+              *r_usage = (sl->flags & 0xff);
+              if (addmode)
+                *r_usage &= ~GCRY_PK_USAGE_CERT;
+            }
+          free_strlist (keypairlist);
+          break;
+       }
       else
         tty_printf (_("Invalid selection.\n"));
 
+    ask_again:
+      ;
     }
 
   xfree(answer);
@@ -2919,11 +3062,14 @@ generate_user_id (KBNODE keyblock, const char *uidstr)
  * this is useful if for example the default algorithm is used for a
  * subkey.  */
 static gpg_error_t
-parse_key_parameter_part (char *string, int for_subkey, int clear_cert,
+parse_key_parameter_part (ctrl_t ctrl,
+                          char *string, int for_subkey, int clear_cert,
                           int *r_algo, unsigned int *r_size,
                           unsigned int *r_keyuse,
-                          char const **r_curve)
+                          char const **r_curve,
+                          char **r_keygrip)
 {
+  gpg_error_t err;
   char *flags;
   int algo;
   char *endp;
@@ -2933,6 +3079,8 @@ parse_key_parameter_part (char *string, int for_subkey, int clear_cert,
   int keyuse;
   int i;
   const char *s;
+  int from_card = 0;
+  char *keygrip = NULL;
 
   if (!string || !*string)
     return 0; /* Success.  */
@@ -2942,7 +3090,9 @@ parse_key_parameter_part (char *string, int for_subkey, int clear_cert,
     *flags++ = 0;
 
   algo = 0;
-  if (strlen (string) >= 3 && (digitp (string+3) || !string[3]))
+  if (!ascii_strcasecmp (string, "card"))
+    from_card = 1;
+  else if (strlen (string) >= 3 && (digitp (string+3) || !string[3]))
     {
       if (!ascii_memcasecmp (string, "rsa", 3))
         algo = PUBKEY_ALGO_RSA;
@@ -2951,7 +3101,10 @@ parse_key_parameter_part (char *string, int for_subkey, int clear_cert,
       else if (!ascii_memcasecmp (string, "elg", 3))
         algo = PUBKEY_ALGO_ELGAMAL_E;
     }
-  if (algo)
+
+  if (from_card)
+    ; /* We need the flags before we can figure out the key to use.  */
+  else if (algo)
     {
       if (!string[3])
         size = get_keysize_range (algo, NULL, NULL);
@@ -2996,7 +3149,7 @@ parse_key_parameter_part (char *string, int for_subkey, int clear_cert,
             keyuse |= PUBKEY_USAGE_AUTH;
           else if (!ascii_strcasecmp (s, "cert"))
             keyuse |= PUBKEY_USAGE_CERT;
-          else if (!ascii_strcasecmp (s, "ecdsa"))
+          else if (!ascii_strcasecmp (s, "ecdsa") && !from_card)
             {
               if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA)
                 algo = PUBKEY_ALGO_ECDSA;
@@ -3007,7 +3160,7 @@ parse_key_parameter_part (char *string, int for_subkey, int clear_cert,
                 }
               ecdh_or_ecdsa = 0;
             }
-          else if (!ascii_strcasecmp (s, "ecdh"))
+          else if (!ascii_strcasecmp (s, "ecdh") && !from_card)
             {
               if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA)
                 algo = PUBKEY_ALGO_ECDH;
@@ -3018,7 +3171,7 @@ parse_key_parameter_part (char *string, int for_subkey, int clear_cert,
                 }
               ecdh_or_ecdsa = 0;
             }
-          else if (!ascii_strcasecmp (s, "eddsa"))
+          else if (!ascii_strcasecmp (s, "eddsa") && !from_card)
             {
               /* Not required but we allow it for consistency.  */
               if (algo == PUBKEY_ALGO_EDDSA)
@@ -3039,8 +3192,115 @@ parse_key_parameter_part (char *string, int for_subkey, int clear_cert,
       xfree (tokens);
     }
 
-  /* If not yet decided switch between ecdh and ecdsa.  */
-  if (ecdh_or_ecdsa && keyuse)
+  /* If not yet decided switch between ecdh and ecdsa unless we want
+   * to read the algo from the current card.  */
+  if (from_card)
+    {
+      strlist_t keypairlist, sl;
+      char *reqkeyref;
+
+      if (!keyuse)
+        keyuse = (for_subkey? PUBKEY_USAGE_ENC
+                  /* */     : (PUBKEY_USAGE_CERT|PUBKEY_USAGE_SIG));
+
+      /* Access the card to make sure we have one and to show the S/N.  */
+      {
+        char *serialno;
+
+        err = agent_scd_serialno (&serialno, NULL);
+        if (err)
+          {
+            log_error (_("error reading the card: %s\n"), gpg_strerror (err));
+            return err;
+          }
+        if (!opt.quiet)
+          log_info (_("Serial number of the card: %s\n"), serialno);
+        xfree (serialno);
+      }
+
+      err = agent_scd_keypairinfo (ctrl, &keypairlist);
+      if (err)
+        {
+          log_error (_("error reading the card: %s\n"), gpg_strerror (err));
+          return err;
+        }
+      agent_scd_getattr_one ((keyuse & (PUBKEY_USAGE_SIG|PUBKEY_USAGE_CERT))
+                             ? "$SIGNKEYID":"$ENCRKEYID", &reqkeyref);
+
+      algo = 0; /* Should already be the case.  */
+      for (sl=keypairlist; sl && !algo; sl = sl->next)
+        {
+          gcry_sexp_t s_pkey;
+          char *algostr = NULL;
+          enum gcry_pk_algos algoid = 0;
+          const char *keyref;
+
+          if (!reqkeyref)
+            continue; /* Card does not provide the info (skip all).  */
+
+          keyref = strchr (sl->d, ' ');
+          if (!keyref)
+            continue; /* Ooops.  */
+          keyref++;
+          if (strcmp (reqkeyref, keyref))
+            continue;  /* This is not the requested keyref.  */
+
+          if ((keyuse & (PUBKEY_USAGE_SIG|PUBKEY_USAGE_CERT))
+              && (sl->flags & (GCRY_PK_USAGE_SIGN|GCRY_PK_USAGE_CERT)))
+            ; /* Okay */
+          else if ((keyuse & PUBKEY_USAGE_ENC)
+                   && (sl->flags & GCRY_PK_USAGE_ENCR))
+            ; /* Okay */
+          else
+            continue; /* Not usable for us.  */
+
+          if (agent_scd_readkey (keyref, &s_pkey))
+            continue;  /* Could not read the key.  */
+
+          algostr = pubkey_algo_string (s_pkey, &algoid);
+          gcry_sexp_release (s_pkey);
+
+
+          /* Map to OpenPGP algo number.
+           * We need to tweak the algo in case GCRY_PK_ECC is returned
+           * because pubkey_algo_string is not aware of the OpenPGP
+           * algo mapping.  FIXME: This is an ugly hack. */
+          if (algoid == GCRY_PK_ECC
+              && algostr && !strncmp (algostr, "nistp", 5)
+              && !(sl->flags & GCRY_PK_USAGE_ENCR))
+            algo = PUBKEY_ALGO_ECDSA;
+          else if (algoid == GCRY_PK_ECC
+                   && algostr && !strcmp (algostr, "ed25519")
+                   && !(sl->flags & GCRY_PK_USAGE_ENCR))
+            algo = PUBKEY_ALGO_EDDSA;
+          else
+            algo = map_pk_gcry_to_openpgp (algoid);
+
+          xfree (algostr);
+          xfree (keygrip);
+          keygrip = xtrystrdup (sl->d);
+          if (!keygrip)
+            {
+              err = gpg_error_from_syserror ();
+              xfree (reqkeyref);
+              free_strlist (keypairlist);
+              return err;
+            }
+          if ((endp = strchr (keygrip, ' ')))
+            *endp = 0;
+        }
+
+      xfree (reqkeyref);
+      free_strlist (keypairlist);
+      if (!algo || !keygrip)
+        {
+          err = gpg_error (GPG_ERR_PUBKEY_ALGO);
+          log_error ("no usable key on the card: %s\n", gpg_strerror (err));
+          xfree (keygrip);
+          return err;
+        }
+    }
+  else if (ecdh_or_ecdsa && keyuse)
     algo = (keyuse & PUBKEY_USAGE_ENC)? PUBKEY_ALGO_ECDH : PUBKEY_ALGO_ECDSA;
   else if (ecdh_or_ecdsa)
     algo = for_subkey? PUBKEY_ALGO_ECDH : PUBKEY_ALGO_ECDSA;
@@ -3080,7 +3340,10 @@ parse_key_parameter_part (char *string, int for_subkey, int clear_cert,
        || ((keyuse & PUBKEY_USAGE_ENC)
            && !pubkey_get_nenc (algo))
        || (for_subkey && (keyuse & PUBKEY_USAGE_CERT)))
-    return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
+    {
+      xfree (keygrip);
+      return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
+    }
 
   /* Return values.  */
   if (r_algo)
@@ -3100,11 +3363,17 @@ parse_key_parameter_part (char *string, int for_subkey, int clear_cert,
 
       *r_size = fixup_keysize (size, algo, 1);
     }
+
   if (r_keyuse)
     *r_keyuse = keyuse;
   if (r_curve)
     *r_curve = curve;
 
+  if (r_keygrip)
+    *r_keygrip = keygrip;
+  else
+    xfree (keygrip);
+
   return 0;
 }
 
@@ -3125,7 +3394,7 @@ parse_key_parameter_part (char *string, int for_subkey, int clear_cert,
  *
  * All strings with an unknown prefix are considered an elliptic
  * curve.  Curves which have no implicit algorithm require that FLAGS
- * is given to select whether ECDSA or ECDH is used; this can eoither
+ * is given to select whether ECDSA or ECDH is used; this can either
  * be done using an algorithm keyword or usage keywords.
  *
  * FLAGS is a comma delimited string of keywords:
@@ -3151,14 +3420,17 @@ parse_key_parameter_part (char *string, int for_subkey, int clear_cert,
  *
  */
 gpg_error_t
-parse_key_parameter_string (const char *string, int part,
+parse_key_parameter_string (ctrl_t ctrl,
+                            const char *string, int part,
                             unsigned int suggested_use,
                             int *r_algo, unsigned int *r_size,
                             unsigned int *r_keyuse,
                             char const **r_curve,
+                            char **r_keygrip,
                             int *r_subalgo, unsigned int *r_subsize,
-                            unsigned *r_subkeyuse,
-                            char const **r_subcurve)
+                            unsigned int *r_subkeyuse,
+                            char const **r_subcurve,
+                            char **r_subkeygrip)
 {
   gpg_error_t err = 0;
   char *primary, *secondary;
@@ -3171,6 +3443,8 @@ parse_key_parameter_string (const char *string, int part,
     *r_keyuse = 0;
   if (r_curve)
     *r_curve = NULL;
+  if (r_keygrip)
+    *r_keygrip = NULL;
   if (r_subalgo)
     *r_subalgo = 0;
   if (r_subsize)
@@ -3179,6 +3453,8 @@ parse_key_parameter_string (const char *string, int part,
     *r_subkeyuse = 0;
   if (r_subcurve)
     *r_subcurve = NULL;
+  if (r_subkeygrip)
+    *r_subkeygrip = NULL;
 
   if (!string || !*string
       || !ascii_strcasecmp (string, "default") || !strcmp (string, "-"))
@@ -3186,6 +3462,8 @@ parse_key_parameter_string (const char *string, int part,
   else if (!ascii_strcasecmp (string, "future-default")
            || !ascii_strcasecmp (string, "futuredefault"))
     string = FUTURE_STD_KEY_PARAM;
+  else if (!ascii_strcasecmp (string, "card"))
+    string = "card/cert,sign+card/encr";
 
   primary = xstrdup (string);
   secondary = strchr (primary, '+');
@@ -3193,11 +3471,14 @@ parse_key_parameter_string (const char *string, int part,
     *secondary++ = 0;
   if (part == -1 || part == 0)
     {
-      err = parse_key_parameter_part (primary, 0, 0, r_algo, r_size,
-                                      r_keyuse, r_curve);
+      err = parse_key_parameter_part (ctrl, primary,
+                                      0, 0, r_algo, r_size,
+                                      r_keyuse, r_curve, r_keygrip);
       if (!err && part == -1)
-        err = parse_key_parameter_part (secondary, 1, 0, r_subalgo, r_subsize,
-                                        r_subkeyuse, r_subcurve);
+        err = parse_key_parameter_part (ctrl, secondary,
+                                        1, 0, r_subalgo, r_subsize,
+                                        r_subkeyuse, r_subcurve,
+                                        r_subkeygrip);
     }
   else if (part == 1)
     {
@@ -3209,15 +3490,21 @@ parse_key_parameter_string (const char *string, int part,
        * to force clearing the cert usage. */
       if (secondary)
         {
-          err = parse_key_parameter_part (secondary, 1, 0,
-                                          r_algo, r_size, r_keyuse, r_curve);
+          err = parse_key_parameter_part (ctrl, secondary,
+                                          1, 0,
+                                          r_algo, r_size, r_keyuse, r_curve,
+                                          r_keygrip);
           if (!err && suggested_use && r_keyuse && !(suggested_use & *r_keyuse))
-            err = parse_key_parameter_part (primary, 1, 1 /*(clear cert)*/,
-                                            r_algo, r_size, r_keyuse, r_curve);
+            err = parse_key_parameter_part (ctrl, primary,
+                                            1, 1 /*(clear cert)*/,
+                                            r_algo, r_size, r_keyuse, r_curve,
+                                            r_keygrip);
         }
       else
-        err = parse_key_parameter_part (primary, 1, 0,
-                                        r_algo, r_size, r_keyuse, r_curve);
+        err = parse_key_parameter_part (ctrl, primary,
+                                        1, 0,
+                                        r_algo, r_size, r_keyuse, r_curve,
+                                        r_keygrip);
     }
 
   xfree (primary);
@@ -3282,7 +3569,7 @@ get_parameter_passphrase (struct para_data_s *para)
 
 
 static int
-get_parameter_algo( struct para_data_s *para, enum para_name key,
+get_parameter_algo (ctrl_t ctrl, struct para_data_s *para, enum para_name key,
                     int *r_default)
 {
   int i;
@@ -3304,10 +3591,9 @@ get_parameter_algo( struct para_data_s *para, enum para_name key,
        * for the curve etc.  That is a ugly but demanded for backward
        * compatibility with the batch key generation.  It would be
        * better to make full use of parse_key_parameter_string.  */
-      parse_key_parameter_string (NULL, 0, 0,
-                                  &i, NULL, NULL, NULL,
-                                  NULL, NULL, NULL, NULL);
-
+      parse_key_parameter_string (ctrl, NULL, 0, 0,
+                                  &i, NULL, NULL, NULL, NULL,
+                                  NULL, NULL, NULL, NULL, NULL);
       if (r_default)
         *r_default = 1;
     }
@@ -3502,7 +3788,7 @@ proc_parameter_file (ctrl_t ctrl, struct para_data_s *para, const char *fname,
   r = get_parameter( para, pKEYTYPE );
   if(r)
     {
-      algo = get_parameter_algo (para, pKEYTYPE, &is_default);
+      algo = get_parameter_algo (ctrl, para, pKEYTYPE, &is_default);
       if (openpgp_pk_test_algo2 (algo, PUBKEY_USAGE_SIG))
        {
          log_error ("%s:%d: invalid algorithm\n", fname, r->lnr );
@@ -3544,7 +3830,7 @@ proc_parameter_file (ctrl_t ctrl, struct para_data_s *para, const char *fname,
   r = get_parameter( para, pSUBKEYTYPE );
   if(r)
     {
-      algo = get_parameter_algo (para, pSUBKEYTYPE, &is_default);
+      algo = get_parameter_algo (ctrl, para, pSUBKEYTYPE, &is_default);
       if (openpgp_pk_test_algo (algo))
        {
          log_error ("%s:%d: invalid algorithm\n", fname, r->lnr );
@@ -3902,7 +4188,8 @@ read_parameter_file (ctrl_t ctrl, const char *fname )
 /* Helper for quick_generate_keypair.  */
 static struct para_data_s *
 quickgen_set_para (struct para_data_s *para, int for_subkey,
-                   int algo, int nbits, const char *curve, unsigned int use)
+                   int algo, int nbits, const char *curve, unsigned int use,
+                   const char *keygrip)
 {
   struct para_data_s *r;
 
@@ -3924,7 +4211,15 @@ quickgen_set_para (struct para_data_s *para, int for_subkey,
   r->next = para;
   para = r;
 
-  if (curve)
+  if (keygrip)
+    {
+      r = xmalloc_clear (sizeof *r + strlen (keygrip));
+      r->key = for_subkey? pSUBKEYGRIP : pKEYGRIP;
+      strcpy (r->u.value, keygrip);
+      r->next = para;
+      para = r;
+    }
+  else if (curve)
     {
       r = xmalloc_clear (sizeof *r + strlen (curve));
       r->key = for_subkey? pSUBKEYCURVE : pKEYCURVE;
@@ -4028,7 +4323,8 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid, const char *algostr,
 
   if ((!*algostr || !ascii_strcasecmp (algostr, "default")
        || !ascii_strcasecmp (algostr, "future-default")
-       || !ascii_strcasecmp (algostr, "futuredefault"))
+       || !ascii_strcasecmp (algostr, "futuredefault")
+       || !ascii_strcasecmp (algostr, "card"))
       && (!*usagestr || !ascii_strcasecmp (usagestr, "default")
           || !strcmp (usagestr, "-")))
     {
@@ -4037,22 +4333,25 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid, const char *algostr,
       unsigned int size, subsize;
       unsigned int keyuse, subkeyuse;
       const char *curve, *subcurve;
+      char *keygrip, *subkeygrip;
 
-      err = parse_key_parameter_string (algostr, -1, 0,
+      err = parse_key_parameter_string (ctrl, algostr, -1, 0,
                                         &algo, &size, &keyuse, &curve,
+                                        &keygrip,
                                         &subalgo, &subsize, &subkeyuse,
-                                        &subcurve);
+                                        &subcurve, &subkeygrip);
       if (err)
         {
           log_error (_("Key generation failed: %s\n"), gpg_strerror (err));
           goto leave;
         }
 
-      para = quickgen_set_para (para, 0, algo, size, curve, keyuse);
+      para = quickgen_set_para (para, 0, algo, size, curve, keyuse,
+                                keygrip);
       if (subalgo)
         para = quickgen_set_para (para, 1,
-                                  subalgo, subsize, subcurve, subkeyuse);
-
+                                  subalgo, subsize, subcurve, subkeyuse,
+                                  subkeygrip);
       if (*expirestr)
         {
           u32 expire;
@@ -4070,6 +4369,9 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid, const char *algostr,
           r->next = para;
           para = r;
         }
+
+      xfree (keygrip);
+      xfree (subkeygrip);
     }
   else
     {
@@ -4079,21 +4381,26 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid, const char *algostr,
       u32 expire;
       unsigned int nbits;
       const char *curve;
+      char *keygrip;
 
       err = parse_algo_usage_expire (ctrl, 0, algostr, usagestr, expirestr,
-                                     &algo, &use, &expire, &nbits, &curve);
+                                     &algo, &use, &expire, &nbits, &curve,
+                                     &keygrip);
       if (err)
         {
           log_error (_("Key generation failed: %s\n"), gpg_strerror (err) );
           goto leave;
         }
 
-      para = quickgen_set_para (para, 0, algo, nbits, curve, use);
+      para = quickgen_set_para (para, 0, algo, nbits, curve, use,
+                                keygrip);
       r = xmalloc_clear (sizeof *r + 20);
       r->key = pKEYEXPIRE;
       r->u.expire = expire;
       r->next = para;
       para = r;
+
+      xfree (keygrip);
     }
 
   /* If the pinentry loopback mode is not and we have a static
@@ -4406,6 +4713,7 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
       unsigned int size, subsize;
       unsigned int keyuse, subkeyuse;
       const char *curve, *subcurve;
+      char *keygrip, *subkeygrip;
 
       tty_printf ( _("Note: Use \"%s %s\""
                      " for a full featured key generation dialog.\n"),
@@ -4416,21 +4724,27 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
 #endif
                    , "--full-generate-key" );
 
-      err = parse_key_parameter_string (NULL, -1, 0,
+      err = parse_key_parameter_string (ctrl, NULL, -1, 0,
                                         &algo, &size, &keyuse, &curve,
+                                        &keygrip,
                                         &subalgo, &subsize,
-                                        &subkeyuse, &subcurve);
+                                        &subkeyuse, &subcurve,
+                                        &subkeygrip);
       if (err)
         {
           log_error (_("Key generation failed: %s\n"), gpg_strerror (err));
           return;
         }
-      para = quickgen_set_para (para, 0, algo, size, curve, keyuse);
+      para = quickgen_set_para (para, 0,
+                                algo, size, curve, keyuse,
+                                keygrip);
       if (subalgo)
         para = quickgen_set_para (para, 1,
-                                  subalgo, subsize, subcurve, subkeyuse);
-
+                                  subalgo, subsize, subcurve, subkeyuse,
+                                  subkeygrip);
 
+      xfree (keygrip);
+      xfree (subkeygrip);
     }
 
 
@@ -4713,7 +5027,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
      node of the subkey but that is more work than just to pass the
      current timestamp.  */
 
-  algo = get_parameter_algo( para, pKEYTYPE, NULL );
+  algo = get_parameter_algo (ctrl, para, pKEYTYPE, NULL );
   expire = get_parameter_u32( para, pKEYEXPIRE );
   key_from_hexgrip = get_parameter_value (para, pKEYGRIP);
   if (key_from_hexgrip)
@@ -4771,7 +5085,8 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
 
   if (!err && card && get_parameter (para, pAUTHKEYTYPE))
     {
-      err = gen_card_key (3, get_parameter_algo( para, pAUTHKEYTYPE, NULL ),
+      err = gen_card_key (3, get_parameter_algo (ctrl, para,
+                                                 pAUTHKEYTYPE, NULL ),
                           0, pub_root, &timestamp, expire);
       if (!err)
         err = write_keybinding (ctrl, pub_root, pri_psk, NULL,
@@ -4780,7 +5095,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
 
   if (!err && get_parameter (para, pSUBKEYTYPE))
     {
-      int subkey_algo = get_parameter_algo (para, pSUBKEYTYPE, NULL);
+      int subkey_algo = get_parameter_algo (ctrl, para, pSUBKEYTYPE, NULL);
 
       s = NULL;
       key_from_hexgrip = get_parameter_value (para, pSUBKEYGRIP);
@@ -4869,7 +5184,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
           int no_enc_rsa;
           PKT_public_key *pk;
 
-          no_enc_rsa = ((get_parameter_algo (para, pKEYTYPE, NULL)
+          no_enc_rsa = ((get_parameter_algo (ctrl, para, pKEYTYPE, NULL)
                          == PUBKEY_ALGO_RSA)
                         && get_parameter_uint (para, pKEYUSAGE)
                         && !((get_parameter_uint (para, pKEYUSAGE)
@@ -4902,7 +5217,8 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
 
 
           if (!opt.batch
-              && (get_parameter_algo (para, pKEYTYPE, NULL) == PUBKEY_ALGO_DSA
+              && (get_parameter_algo (ctrl, para,
+                                      pKEYTYPE, NULL) == PUBKEY_ALGO_DSA
                   || no_enc_rsa )
               && !get_parameter (para, pSUBKEYTYPE) )
             {
@@ -4941,7 +5257,8 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
                          const char *algostr, const char *usagestr,
                          const char *expirestr,
                          int *r_algo, unsigned int *r_usage, u32 *r_expire,
-                         unsigned int *r_nbits, const char **r_curve)
+                         unsigned int *r_nbits, const char **r_curve,
+                         char **r_keygrip)
 {
   gpg_error_t err;
   int algo;
@@ -4951,6 +5268,8 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
   const char *curve = NULL;
 
   *r_curve = NULL;
+  if (r_keygrip)
+    *r_keygrip = NULL;
 
   nbits = 0;
 
@@ -4963,12 +5282,20 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
       return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     }
 
-  err = parse_key_parameter_string (algostr, for_subkey? 1 : 0,
+  err = parse_key_parameter_string (ctrl, algostr, for_subkey? 1 : 0,
                                     usagestr? parse_usagestr (usagestr):0,
                                     &algo, &nbits, &use, &curve,
-                                    NULL, NULL, NULL, NULL);
+                                    r_keygrip,
+                                    NULL, NULL, NULL, NULL, NULL);
   if (err)
-    return err;
+    {
+      if (r_keygrip)
+        {
+          xfree (*r_keygrip);
+          *r_keygrip = NULL;
+        }
+      return err;
+    }
 
   /* Parse the usage string.  */
   if (!usagestr || !*usagestr
@@ -4977,7 +5304,14 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
   else if ((wantuse = parse_usagestr (usagestr)) != -1)
     use = wantuse;
   else
-    return gpg_error (GPG_ERR_INV_VALUE);
+    {
+      if (r_keygrip)
+        {
+          xfree (*r_keygrip);
+          *r_keygrip = NULL;
+        }
+      return gpg_error (GPG_ERR_INV_VALUE);
+    }
 
   /* Make sure a primary key has the CERT usage.  */
   if (!for_subkey)
@@ -4991,12 +5325,26 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
        || ((use & PUBKEY_USAGE_ENC)
            && !pubkey_get_nenc (algo))
        || (for_subkey && (use & PUBKEY_USAGE_CERT)))
-    return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
+    {
+      if (r_keygrip)
+        {
+          xfree (*r_keygrip);
+          *r_keygrip = NULL;
+        }
+      return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
+    }
 
   /* Parse the expire string.  */
   expire = parse_expire_string (expirestr);
   if (expire == (u32)-1 )
-    return gpg_error (GPG_ERR_INV_VALUE);
+    {
+      if (r_keygrip)
+        {
+          xfree (*r_keygrip);
+          *r_keygrip = NULL;
+        }
+      return gpg_error (GPG_ERR_INV_VALUE);
+    }
 
   if (curve)
     *r_curve = curve;
@@ -5113,7 +5461,8 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr,
   else /* Unattended mode.  */
     {
       err = parse_algo_usage_expire (ctrl, 1, algostr, usagestr, expirestr,
-                                     &algo, &use, &expire, &nbits, &curve);
+                                     &algo, &use, &expire, &nbits, &curve,
+                                     &key_from_hexgrip);
       if (err)
         goto leave;
     }
index 62b7875..13f27cb 100644 (file)
@@ -523,7 +523,11 @@ list_all (ctrl_t ctrl, int secret, int mark_secret)
   lastresname = NULL;
   do
     {
+      if (secret)
+        glo_ctrl.silence_parse_warnings++;
       rc = keydb_get_keyblock (hd, &keyblock);
+      if (secret)
+        glo_ctrl.silence_parse_warnings--;
       if (rc)
        {
           if (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY)
index a8dd462..f424f94 100644 (file)
@@ -473,11 +473,14 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb)
         }
 
         in_cert = 1;
-        node = lastnode = new_kbnode (pkt);
+        node = new_kbnode (pkt);
         if (!keyblock)
-          keyblock = node;
+          keyblock = lastnode = node;
         else
-          add_kbnode (keyblock, node);
+          {
+            lastnode->next = node;
+            lastnode = node;
+          }
         switch (pkt->pkttype)
           {
           case PKT_PUBLIC_KEY:
index 16efeee..0183777 100644 (file)
@@ -1833,9 +1833,10 @@ keyserver_put (ctrl_t ctrl, strlist_t keyspecs)
         log_error (_("skipped \"%s\": %s\n"), kspec->d, gpg_strerror (err));
       else
         {
-          log_info (_("sending key %s to %s\n"),
-                    keystr (keyblock->pkt->pkt.public_key->keyid),
-                    ksurl?ksurl:"[?]");
+          if (!opt.quiet)
+            log_info (_("sending key %s to %s\n"),
+                      keystr (keyblock->pkt->pkt.public_key->keyid),
+                      ksurl?ksurl:"[?]");
 
           err = gpg_dirmngr_ks_put (ctrl, data, datalen, keyblock);
           release_kbnode (keyblock);
index 9136e4c..90e164f 100644 (file)
@@ -91,6 +91,7 @@ void print_pubkey_algo_note (pubkey_algo_t algo);
 void print_cipher_algo_note (cipher_algo_t algo);
 void print_digest_algo_note (digest_algo_t algo);
 void print_digest_rejected_note (enum gcry_md_algos algo);
+void print_sha1_keysig_rejected_note (void);
 void print_reported_error (gpg_error_t err, gpg_err_code_t skip_if_ec);
 void print_further_info (const char *format, ...) GPGRT_ATTR_PRINTF(1,2);
 void additional_weak_digest (const char* digestname);
index 6d525a8..291d36f 100644 (file)
@@ -357,6 +357,24 @@ print_digest_rejected_note (enum gcry_md_algos algo)
 }
 
 
+void
+print_sha1_keysig_rejected_note (void)
+{
+  static int shown;
+
+  if (shown)
+    return;
+
+  shown = 1;
+  es_fflush (es_stdout);
+  log_info (_("Note: third-party key signatures using"
+              " the %s algorithm are rejected\n"),
+            gcry_md_algo_name (GCRY_MD_SHA1));
+  print_further_info ("use option \"%s\" to override",
+                      "--allow-weak-key-signatures");
+}
+
+
 /* Print a message
  *  "(reported error: %s)\n
  * in verbose mode to further explain an error.  If the error code has
index 0f007c1..4510819 100644 (file)
@@ -237,12 +237,16 @@ struct
     unsigned int dsa2:1;
     unsigned int allow_multiple_messages:1;
     unsigned int allow_weak_digest_algos:1;
+    unsigned int allow_weak_key_signatures:1;
     unsigned int large_rsa:1;
     unsigned int disable_signer_uid:1;
     /* Flag to enable experimental features from RFC4880bis.  */
     unsigned int rfc4880bis:1;
     /* Hack: --output is not given but OUTFILE was temporary set to "-".  */
     unsigned int dummy_outfile:1;
+    /* Force the use of the OpenPGP card and do not allow the use of
+     * another card.  */
+    unsigned int use_only_openpgp_card:1;
   } flags;
 
   /* Linked list of ways to find a key if the key isn't on the local
@@ -290,6 +294,9 @@ struct {
      codes.  Thus for the --server purposes we store some of the error
      codes here.  FIXME! */
   gpg_error_t lasterr;
+
+  /* Kludge to silence some warnings using --secret-key-list. */
+  int silence_parse_warnings;
 } glo_ctrl;
 
 #define DBG_PACKET_VALUE  1    /* debug packet reading/writing */
index 2d6ec92..85d8f33 100644 (file)
@@ -267,7 +267,7 @@ unknown_pubkey_warning (int algo)
      encryption/signing.  */
   if (pubkey_get_npkey (algo))
     {
-      if (opt.verbose)
+      if (opt.verbose && !glo_ctrl.silence_parse_warnings)
         {
           if (!pubkey_get_nsig (algo))
             log_info ("public key algorithm %s not suitable for %s\n",
@@ -282,7 +282,7 @@ unknown_pubkey_warning (int algo)
       algo &= 0xff;
       if (!unknown_pubkey_algos[algo])
         {
-          if (opt.verbose)
+          if (opt.verbose && !glo_ctrl.silence_parse_warnings)
             log_info (_("can't handle public key algorithm %d\n"), algo);
           unknown_pubkey_algos[algo] = 1;
         }
@@ -1641,7 +1641,7 @@ can_handle_critical_notation (const byte *name, size_t len)
     if (sl->flags == len && !memcmp (sl->d, name, len))
       return 1; /* Known */
 
-  if (opt.verbose)
+  if (opt.verbose && !glo_ctrl.silence_parse_warnings)
     {
       log_info(_("Unknown critical signature notation: ") );
       print_utf8_buffer (log_get_stream(), name, len);
@@ -1761,7 +1761,7 @@ enum_sig_subpkt (const subpktarea_t * pktbuf, sigsubpkttype_t reqtype,
                goto too_short;
              if (!can_handle_critical (buffer + 1, n - 1, type))
                {
-                 if (opt.verbose)
+                 if (opt.verbose && !glo_ctrl.silence_parse_warnings)
                    log_info (_("subpacket of type %d has "
                                "critical bit set\n"), type);
                  if (start)
@@ -1812,14 +1812,14 @@ enum_sig_subpkt (const subpktarea_t * pktbuf, sigsubpkttype_t reqtype,
   return NULL; /* End of packets; not found.  */
 
  too_short:
-  if (opt.verbose)
+  if (opt.verbose && !glo_ctrl.silence_parse_warnings)
     log_info ("buffer shorter than subpacket\n");
   if (start)
     *start = -1;
   return NULL;
 
  no_type_byte:
-  if (opt.verbose)
+  if (opt.verbose && !glo_ctrl.silence_parse_warnings)
     log_info ("type octet missing in subpacket\n");
   if (start)
     *start = -1;
@@ -2029,7 +2029,7 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen,
       if (p)
        sig->timestamp = buf32_to_u32 (p);
       else if (!(sig->pubkey_algo >= 100 && sig->pubkey_algo <= 110)
-              && opt.verbose)
+              && opt.verbose && !glo_ctrl.silence_parse_warnings)
        log_info ("signature packet without timestamp\n");
 
       p = parse_sig_subpkt2 (sig, SIGSUBPKT_ISSUER);
@@ -2039,7 +2039,7 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen,
          sig->keyid[1] = buf32_to_u32 (p + 4);
        }
       else if (!(sig->pubkey_algo >= 100 && sig->pubkey_algo <= 110)
-              && opt.verbose)
+              && opt.verbose && !glo_ctrl.silence_parse_warnings)
        log_info ("signature packet without keyid\n");
 
       p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_EXPIRE, NULL);
@@ -2286,7 +2286,9 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
     }
   else if (version == 2 || version == 3)
     {
-      if (opt.verbose > 1)
+      /* Not anymore supported since 2.1.  Use an older gpg version
+       * (i.e. gpg 1.4) to parse v3 packets.  */
+      if (opt.verbose > 1 && !glo_ctrl.silence_parse_warnings)
         log_info ("packet(%d) with obsolete version %d\n", pkttype, version);
       if (list_mode)
         es_fprintf (listfp, ":key packet: [obsolete version %d]\n", version);
@@ -2760,7 +2762,7 @@ parse_attribute_subpkts (PKT_user_id * uid)
   return count;
 
  too_short:
-  if (opt.verbose)
+  if (opt.verbose && !glo_ctrl.silence_parse_warnings)
     log_info ("buffer shorter than attribute subpacket\n");
   uid->attribs = attribs;
   uid->numattribs = count;
index d7ba953..71a48cc 100644 (file)
@@ -305,6 +305,16 @@ get_it (ctrl_t ctrl,
               err = gpg_error (GPG_ERR_WRONG_SECKEY);
               goto leave;
             }
+
+          /* FIXME: Actually the leading zero is required but due to
+           * the way we encode the output in libgcrypt as an MPI we
+           * are not able to encode that leading zero.  However, when
+           * using a Smartcard we are doing it the right way and
+           * therefore we have to skip the zero.  This should be fixed
+           * in gpg-agent of course. */
+          if (!frame[n])
+            n++;
+
           if (frame[n] == 1 && frame[nframe - 1] == 2)
             {
               log_info (_("old encoding of the DEK is not supported\n"));
index a93b496..5ec8247 100644 (file)
@@ -824,6 +824,10 @@ check_signature_over_key_or_uid (ctrl_t ctrl, PKT_public_key *signer,
   PKT_public_key *pripk = kb->pkt->pkt.public_key;
   gcry_md_hd_t md;
   int signer_alloced = 0;
+  int stub_is_selfsig;
+
+  if (!is_selfsig)
+    is_selfsig = &stub_is_selfsig;
 
   rc = openpgp_pk_test_algo (sig->pubkey_algo);
   if (rc)
@@ -857,14 +861,11 @@ check_signature_over_key_or_uid (ctrl_t ctrl, PKT_public_key *signer,
 
   if (signer)
     {
-      if (is_selfsig)
-        {
-          if (signer->keyid[0] == pripk->keyid[0]
-              && signer->keyid[1] == pripk->keyid[1])
-            *is_selfsig = 1;
-          else
-            *is_selfsig = 0;
-        }
+      if (signer->keyid[0] == pripk->keyid[0]
+          && signer->keyid[1] == pripk->keyid[1])
+        *is_selfsig = 1;
+      else
+        *is_selfsig = 0;
     }
   else
     {
@@ -874,8 +875,7 @@ check_signature_over_key_or_uid (ctrl_t ctrl, PKT_public_key *signer,
         {
           /* Issued by the primary key.  */
           signer = pripk;
-          if (is_selfsig)
-            *is_selfsig = 1;
+          *is_selfsig = 1;
         }
       else
         {
@@ -904,8 +904,7 @@ check_signature_over_key_or_uid (ctrl_t ctrl, PKT_public_key *signer,
           if (! signer)
             {
               /* Signer by some other key.  */
-              if (is_selfsig)
-                *is_selfsig = 0;
+              *is_selfsig = 0;
               if (ret_pk)
                 {
                   signer = ret_pk;
@@ -966,9 +965,24 @@ check_signature_over_key_or_uid (ctrl_t ctrl, PKT_public_key *signer,
   else if (IS_UID_SIG (sig) || IS_UID_REV (sig))
     {
       log_assert (packet->pkttype == PKT_USER_ID);
-      hash_public_key (md, pripk);
-      hash_uid_packet (packet->pkt.user_id, md, sig);
-      rc = check_signature_end_simple (signer, sig, md);
+      if (sig->digest_algo == DIGEST_ALGO_SHA1 && !*is_selfsig
+          && sig->timestamp > 1547856000
+          && !opt.flags.allow_weak_key_signatures)
+        {
+          /* If the signature was created using SHA-1 we consider this
+           * signature invalid because it makes it possible to mount a
+           * chosen-prefix collision.  We don't do this for
+           * self-signatures or for signatures created before the
+           * somewhat arbitrary cut-off date 2019-01-19.  */
+          print_sha1_keysig_rejected_note ();
+          rc = gpg_error (GPG_ERR_DIGEST_ALGO);
+        }
+      else
+        {
+          hash_public_key (md, pripk);
+          hash_uid_packet (packet->pkt.user_id, md, sig);
+          rc = check_signature_end_simple (signer, sig, md);
+        }
     }
   else
     {
index 92ff361..01a7045 100644 (file)
 #define LF "\n"
 #endif
 
+/* Bitflags to convey hints on what kind of signayire is created.  */
+#define SIGNHINT_KEYSIG  1
+#define SIGNHINT_SELFSIG 2
+
+
+/* Hack */
 static int recipient_digest_algo=0;
 
+
 /****************
  * Create notations and other stuff.  It is assumed that the stings in
  * STRLIST are already checked to contain only printable data and have
@@ -252,10 +259,12 @@ 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 for the key.  */
+ * advised to use that cached passphrase for the key.  SIGNHINTS has
+ * hints so that we can do some additional checks. */
 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)
+        gcry_md_hd_t md, int mdalgo,
+         const char *cache_nonce, unsigned int signhints)
 {
   gpg_error_t err;
   byte *dp;
@@ -278,6 +287,19 @@ do_sign (ctrl_t ctrl, PKT_public_key *pksk, PKT_signature *sig,
   if (!mdalgo)
     mdalgo = gcry_md_get_algo (md);
 
+  if ((signhints & SIGNHINT_KEYSIG) && !(signhints & SIGNHINT_SELFSIG)
+      && mdalgo == GCRY_MD_SHA1
+      && !opt.flags.allow_weak_key_signatures)
+    {
+      /* We do not allow the creation of third-party key signatures
+       * using SHA-1 because we also reject them when verifying.  Note
+       * that this will render dsa1024 keys unsuitable for such
+       * keysigs and in turn the WoT. */
+      print_sha1_keysig_rejected_note ();
+      err = gpg_error (GPG_ERR_DIGEST_ALGO);
+      goto leave;
+    }
+
   /* Check compliance.  */
   if (! gnupg_digest_is_allowed (opt.compliance, 1, mdalgo))
     {
@@ -374,12 +396,12 @@ do_sign (ctrl_t ctrl, PKT_public_key *pksk, PKT_signature *sig,
 static int
 complete_sig (ctrl_t ctrl,
               PKT_signature *sig, PKT_public_key *pksk, gcry_md_hd_t md,
-              const char *cache_nonce)
+              const char *cache_nonce, unsigned int signhints)
 {
   int rc;
 
   /* if (!(rc = check_secret_key (pksk, 0))) */
-  rc = do_sign (ctrl, pksk, sig, md, 0, cache_nonce);
+  rc = do_sign (ctrl, pksk, sig, md, 0, cache_nonce, signhints);
   return rc;
 }
 
@@ -753,7 +775,7 @@ write_signature_packets (ctrl_t ctrl,
       hash_sigversion_to_magic (md, sig);
       gcry_md_final (md);
 
-      rc = do_sign (ctrl, pk, sig, md, hash_for (pk), cache_nonce);
+      rc = do_sign (ctrl, pk, sig, md, hash_for (pk), cache_nonce, 0);
       gcry_md_close (md);
       if (!rc)
         {
@@ -1468,6 +1490,8 @@ make_keysig_packet (ctrl_t ctrl,
     int rc=0;
     int sigversion;
     gcry_md_hd_t md;
+    u32 pk_keyid[2], pksk_keyid[2];
+    unsigned int signhints;
 
     log_assert ((sigclass >= 0x10 && sigclass <= 0x13) || sigclass == 0x1F
                 || sigclass == 0x20 || sigclass == 0x18 || sigclass == 0x19
@@ -1504,6 +1528,12 @@ make_keysig_packet (ctrl_t ctrl,
          digest_algo = DEFAULT_DIGEST_ALGO;
       }
 
+    signhints = SIGNHINT_KEYSIG;
+    keyid_from_pk (pk, pk_keyid);
+    keyid_from_pk (pksk, pksk_keyid);
+    if (pk_keyid[0] == pksk_keyid[0] && pk_keyid[1] == pksk_keyid[1])
+      signhints |= SIGNHINT_SELFSIG;
+
     if ( gcry_md_open (&md, digest_algo, 0 ) )
       BUG ();
 
@@ -1549,7 +1579,7 @@ make_keysig_packet (ctrl_t ctrl,
         hash_sigversion_to_magic (md, sig);
        gcry_md_final (md);
 
-       rc = complete_sig (ctrl, sig, pksk, md, cache_nonce);
+       rc = complete_sig (ctrl, sig, pksk, md, cache_nonce, signhints);
     }
 
     gcry_md_close (md);
@@ -1585,6 +1615,8 @@ update_keysig_packet (ctrl_t ctrl,
     gpg_error_t rc = 0;
     int digest_algo;
     gcry_md_hd_t md;
+    u32 pk_keyid[2], pksk_keyid[2];
+    unsigned int signhints;
 
     if ((!orig_sig || !pk || !pksk)
        || (orig_sig->sig_class >= 0x10 && orig_sig->sig_class <= 0x13 && !uid)
@@ -1603,6 +1635,12 @@ update_keysig_packet (ctrl_t ctrl,
     else
       digest_algo = orig_sig->digest_algo;
 
+    signhints = SIGNHINT_KEYSIG;
+    keyid_from_pk (pk, pk_keyid);
+    keyid_from_pk (pksk, pksk_keyid);
+    if (pk_keyid[0] == pksk_keyid[0] && pk_keyid[1] == pksk_keyid[1])
+      signhints |= SIGNHINT_SELFSIG;
+
     if ( gcry_md_open (&md, digest_algo, 0 ) )
       BUG ();
 
@@ -1656,7 +1694,7 @@ update_keysig_packet (ctrl_t ctrl,
         hash_sigversion_to_magic (md, sig);
        gcry_md_final (md);
 
-       rc = complete_sig (ctrl, sig, pksk, md, NULL);
+       rc = complete_sig (ctrl, sig, pksk, md, NULL, signhints);
     }
 
  leave:
index 78890dc..8817ee9 100644 (file)
@@ -286,3 +286,310 @@ build_sk_list (ctrl_t ctrl,
     *ret_sk_list = sk_list;
   return err;
 }
+
+
+/* Enumerate some secret keys (specifically, those specified with
+ * --default-key and --try-secret-key).  Use the following procedure:
+ *
+ *  1) Initialize a void pointer to NULL
+ *  2) Pass a reference to this pointer to this function (content)
+ *     and provide space for the secret key (sk)
+ *  3) Call this function as long as it does not return an error (or
+ *     until you are done).  The error code GPG_ERR_EOF indicates the
+ *     end of the listing.
+ *  4) Call this function a last time with SK set to NULL,
+ *     so that can free it's context.
+ *
+ * In pseudo-code:
+ *
+ *   void *ctx = NULL;
+ *   PKT_public_key *sk = xmalloc_clear (sizeof (*sk));
+ *
+ *   while ((err = enum_secret_keys (&ctx, sk)))
+ *     { // Process SK.
+ *       if (done)
+ *         break;
+ *       sk = xmalloc_clear (sizeof (*sk));
+ *     }
+ *
+ *   // Release any resources used by CTX.
+ *   enum_secret_keys (&ctx, NULL);
+ *
+ *   if (gpg_err_code (err) != GPG_ERR_EOF)
+ *     ; // An error occurred.
+ */
+gpg_error_t
+enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk)
+{
+  gpg_error_t err = 0;
+  const char *name;
+  kbnode_t keyblock;
+  struct
+  {
+    int eof;
+    int state;
+    strlist_t sl;
+    strlist_t card_list;
+    char *serialno;
+    char fpr2[2 * MAX_FINGERPRINT_LEN + 3 ];
+    struct agent_card_info_s info;
+    kbnode_t keyblock;
+    kbnode_t node;
+    getkey_ctx_t ctx;
+    SK_LIST results;
+  } *c = *context;
+
+#if MAX_FINGERPRINT_LEN < KEYGRIP_LEN
+# error buffer too short for this configuration
+#endif
+
+  if (!c)
+    {
+      /* Make a new context.  */
+      c = xtrycalloc (1, sizeof *c);
+      if (!c)
+        {
+          err = gpg_error_from_syserror ();
+          free_public_key (sk);
+          return err;
+        }
+      *context = c;
+    }
+
+  if (!sk)
+    {
+      /* Free the context.  */
+      xfree (c->serialno);
+      free_strlist (c->card_list);
+      release_sk_list (c->results);
+      release_kbnode (c->keyblock);
+      getkey_end (ctrl, c->ctx);
+      xfree (c);
+      *context = NULL;
+      return 0;
+    }
+
+  if (c->eof)
+    {
+      free_public_key (sk);
+      return gpg_error (GPG_ERR_EOF);
+    }
+
+  for (;;)
+    {
+      /* Loop until we have a keyblock.  */
+      while (!c->keyblock)
+        {
+          /* Loop over the list of secret keys.  */
+          do
+            {
+              char *serialno;
+
+              name = NULL;
+              keyblock = NULL;
+              switch (c->state)
+                {
+                case 0: /* First try to use the --default-key.  */
+                  name = parse_def_secret_key (ctrl);
+                  c->state = 1;
+                  break;
+
+                case 1: /* Init list of keys to try.  */
+                  c->sl = opt.secret_keys_to_try;
+                  c->state++;
+                  break;
+
+                case 2: /* Get next item from list.  */
+                  if (c->sl)
+                    {
+                      name = c->sl->d;
+                      c->sl = c->sl->next;
+                    }
+                  else
+                    c->state++;
+                  break;
+
+                case 3: /* Init list of card keys to try.  */
+                  err = agent_scd_cardlist (&c->card_list);
+                  if (!err)
+                    agent_scd_serialno (&c->serialno, NULL);
+                  c->sl = c->card_list;
+                  c->state++;
+                  break;
+
+                case 4: /* Get next item from card list.  */
+                  if (c->sl)
+                    {
+                      err = agent_scd_serialno (&serialno, c->sl->d);
+                      if (err)
+                        {
+                          if (opt.verbose)
+                            log_info (_("error getting serial number of card: %s\n"),
+                                      gpg_strerror (err));
+                          c->sl = c->sl->next;
+                          continue;
+                        }
+
+                      xfree (serialno);
+                      err = agent_scd_getattr ("KEY-FPR", &c->info);
+                      if (!err)
+                        {
+                          if (c->info.fpr2valid)
+                            {
+                              c->fpr2[0] = '0';
+                              c->fpr2[1] = 'x';
+                              bin2hex (c->info.fpr2, sizeof c->info.fpr2,
+                                       c->fpr2 + 2);
+                              name = c->fpr2;
+                            }
+                        }
+                      else if (gpg_err_code (err) == GPG_ERR_INV_NAME)
+                        {
+                          /* KEY-FPR not supported by the card - get
+                           * the key using the keygrip.  */
+                          char *keyref;
+                          strlist_t kplist, sl;
+                          const char *s;
+                          int i;
+
+                          err = agent_scd_getattr_one ("$ENCRKEYID", &keyref);
+                          if (!err)
+                            {
+                              err = agent_scd_keypairinfo (ctrl, &kplist);
+                              if (!err)
+                                {
+                                  for (sl = kplist; sl; sl = sl->next)
+                                    if ((s = strchr (sl->d, ' '))
+                                        && !strcmp (s+1, keyref))
+                                      break;
+                                  if (sl)
+                                    {
+                                      c->fpr2[0] = '&';
+                                      for (i=1, s=sl->d;
+                                           (*s && *s != ' '
+                                            && i < sizeof c->fpr2 - 3);
+                                           s++, i++)
+                                        c->fpr2[i] = *s;
+                                      c->fpr2[i] = 0;
+                                      name = c->fpr2;
+                                    }
+                                  else /* Restore error.  */
+                                    err = gpg_error (GPG_ERR_INV_NAME);
+                                  free_strlist (kplist);
+                                }
+                            }
+                          xfree (keyref);
+                        }
+                      if (err)
+                        log_error ("error retrieving key from card: %s\n",
+                                   gpg_strerror (err));
+
+                      c->sl = c->sl->next;
+                    }
+                  else
+                    {
+                      serialno = c->serialno;
+                      if (serialno)
+                        {
+                          /* Select the original card again.  */
+                          agent_scd_serialno (&c->serialno, serialno);
+                          xfree (serialno);
+                        }
+                      c->state++;
+                    }
+                  break;
+
+                case 5: /* Init search context to enum all secret keys.  */
+                  err = getkey_bynames (ctrl, &c->ctx, NULL, NULL, 1,
+                                        &keyblock);
+                  if (err)
+                    {
+                      release_kbnode (keyblock);
+                      keyblock = NULL;
+                      getkey_end (ctrl, c->ctx);
+                      c->ctx = NULL;
+                    }
+                  c->state++;
+                  break;
+
+                case 6: /* Get next item from the context.  */
+                  if (c->ctx)
+                    {
+                      err = getkey_next (ctrl, c->ctx, NULL, &keyblock);
+                      if (err)
+                        {
+                          release_kbnode (keyblock);
+                          keyblock = NULL;
+                          getkey_end (ctrl, c->ctx);
+                          c->ctx = NULL;
+                        }
+                    }
+                  else
+                    c->state++;
+                  break;
+
+                default: /* No more names to check - stop.  */
+                  c->eof = 1;
+                  free_public_key (sk);
+                  return gpg_error (GPG_ERR_EOF);
+                }
+            }
+          while ((!name || !*name) && !keyblock);
+
+          if (keyblock)
+            c->node = c->keyblock = keyblock;
+          else
+            {
+              err = getkey_byname (ctrl, NULL, NULL, name, 1, &c->keyblock);
+              if (err)
+                {
+                  /* getkey_byname might return a keyblock even in the
+                     error case - I have not checked.  Thus better release
+                     it.  */
+                  release_kbnode (c->keyblock);
+                  c->keyblock = NULL;
+                }
+              else
+                c->node = c->keyblock;
+            }
+        }
+
+      /* Get the next key from the current keyblock.  */
+      for (; c->node; c->node = c->node->next)
+        {
+          if (c->node->pkt->pkttype == PKT_PUBLIC_KEY
+              || c->node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+            {
+              SK_LIST r;
+
+              /* Skip this candidate if it's already enumerated.  */
+              for (r = c->results; r; r = r->next)
+                if (!cmp_public_keys (r->pk, c->node->pkt->pkt.public_key))
+                  break;
+              if (r)
+                continue;
+
+              copy_public_key (sk, c->node->pkt->pkt.public_key);
+              c->node = c->node->next;
+
+              r = xtrycalloc (1, sizeof (*r));
+              if (!r)
+                {
+                  err = gpg_error_from_syserror ();
+                  free_public_key (sk);
+                  return err;
+                }
+
+              r->pk = sk;
+              r->next = c->results;
+              c->results = r;
+
+              return 0; /* Found.  */
+            }
+        }
+
+      /* Dispose the keyblock and continue.  */
+      release_kbnode (c->keyblock);
+      c->keyblock = NULL;
+    }
+}
index 8ef6db5..e7d254c 100644 (file)
@@ -303,7 +303,9 @@ verify_own_keys (ctrl_t ctrl)
              release_public_key_parts (&pk);
            }
 
-          log_info (_("key %s marked as ultimately trusted\n"),keystr(k->kid));
+          if (!opt.quiet)
+            log_info (_("key %s marked as ultimately trusted\n"),
+                      keystr(k->kid));
         }
     }
 
index aa1d93b..3bafbaa 100644 (file)
@@ -573,6 +573,7 @@ _keybox_dump_file (const char *filename, int stats_only, FILE *outfp)
   int rc;
   unsigned long count = 0;
   struct file_stats_s stats;
+  int skipped_deleted;
 
   memset (&stats, 0, sizeof stats);
 
@@ -581,7 +582,7 @@ _keybox_dump_file (const char *filename, int stats_only, FILE *outfp)
 
   for (;;)
     {
-      rc = _keybox_read_blob (&blob, fp, NULL);
+      rc = _keybox_read_blob (&blob, fp, &skipped_deleted);
       if (gpg_err_code (rc) == GPG_ERR_TOO_LARGE
           && gpg_err_source (rc) == GPG_ERR_SOURCE_KEYBOX)
         {
@@ -598,8 +599,12 @@ _keybox_dump_file (const char *filename, int stats_only, FILE *outfp)
       if (rc)
         break;
 
+      count += skipped_deleted;
+
       if (stats_only)
         {
+          stats.total_blob_count += skipped_deleted;
+          stats.empty_blob_count += skipped_deleted;
           update_stats (blob, &stats);
         }
       else
index 6d656f2..e6c3ad2 100644 (file)
@@ -262,9 +262,12 @@ _keybox_close_file (KEYBOX_HANDLE hd)
 
 /*
  * Lock the keybox at handle HD, or unlock if YES is false.
+ * Lock the keybox at handle HD, or unlock if YES is false.  TIMEOUT
+ * is the value used for dotlock_take.  In general -1 should be used
+ * when taking a lock; use 0 when releasing a lock.
  */
 gpg_error_t
-keybox_lock (KEYBOX_HANDLE hd, int yes)
+keybox_lock (KEYBOX_HANDLE hd, int yes, long timeout)
 {
   gpg_error_t err = 0;
   KB_NAME kb = hd->kb;
@@ -298,10 +301,13 @@ keybox_lock (KEYBOX_HANDLE hd, int yes)
            * in a deadlock.  */
           _keybox_close_file (hd);
 #endif /*HAVE_W32_SYSTEM*/
-          if (dotlock_take (kb->lockhd, -1))
+          if (dotlock_take (kb->lockhd, timeout))
             {
               err = gpg_error_from_syserror ();
-              log_info ("can't lock '%s'\n", kb->fname );
+              if (!timeout && gpg_err_code (err) == GPG_ERR_EACCES)
+                ; /* No diagnostic if we only tried to lock.  */
+              else
+                log_info ("can't lock '%s'\n", kb->fname );
             }
           else
             kb->is_locked = 1;
index e09fefc..e25596b 100644 (file)
@@ -675,7 +675,7 @@ keybox_compress (KEYBOX_HANDLE hd)
         {
           u32 last_maint = buf32_to_u32 (buffer+20);
 
-          if ( (last_maint + 3*3600) > time (NULL) )
+          if ( (last_maint + 3*3600) > make_timestamp () )
             {
               fclose (fp);
               _keybox_release_blob (blob);
@@ -700,7 +700,7 @@ keybox_compress (KEYBOX_HANDLE hd)
      automagically skip any blobs flagged as deleted.  Thus what we
      only have to do is to check all ephemeral flagged blocks whether
      their time has come and write out all other blobs. */
-  cut_time = time(NULL) - 86400;
+  cut_time = make_timestamp () - 86400;
   first_blob = 1;
   skipped_deleted = 0;
   for (rc=0; !(read_rc = _keybox_read_blob (&blob, fp, &skipped_deleted));
index 665b05f..4d94157 100644 (file)
@@ -76,7 +76,7 @@ void keybox_pop_found_state (KEYBOX_HANDLE hd);
 const char *keybox_get_resource_name (KEYBOX_HANDLE hd);
 int keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes);
 
-gpg_error_t keybox_lock (KEYBOX_HANDLE hd, int yes);
+gpg_error_t keybox_lock (KEYBOX_HANDLE hd, int yes, long timeout);
 
 /*-- keybox-file.c --*/
 /* Fixme: This function does not belong here: Provide a better
index abcdef3..e6bd38d 100644 (file)
--- a/po/ca.po
+++ b/po/ca.po
@@ -114,6 +114,7 @@ msgstr ""
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -1401,14 +1402,11 @@ msgstr "La vostra selecció? "
 msgid "[not set]"
 msgstr "[no establert]"
 
-msgid "male"
-msgstr "home"
-
-msgid "female"
-msgstr "dóna"
+msgid "Mr."
+msgstr ""
 
-msgid "unspecified"
-msgstr "no especificat"
+msgid "Ms."
+msgstr ""
 
 # Gènere?  Nombre?  Passat, futur?  ivb
 # Probablement és una clau, femení. jm
@@ -1470,7 +1468,7 @@ msgstr "hi ha un caràcter invàlid en la cadena de preferència\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "hi ha un caràcter invàlid en la cadena de preferència\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
 msgstr ""
 
 #, fuzzy
@@ -1654,7 +1652,7 @@ msgstr "canvia la data de caducitat"
 msgid "change the language preferences"
 msgstr "canvia la confiança"
 
-msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr ""
 
 #, fuzzy
@@ -4200,14 +4198,14 @@ msgid "Authenticate"
 msgstr ""
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr ""
@@ -4289,6 +4287,10 @@ msgstr "   (%d) RSA (només xifrar)\n"
 msgid "  (%d) Existing key\n"
 msgstr "   (%d) RSA (només xifrar)\n"
 
+#, fuzzy, c-format
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) RSA (només xifrar)\n"
+
 #, fuzzy
 msgid "Enter the keygrip: "
 msgstr "Notació de signatura: "
@@ -4301,6 +4303,18 @@ msgid "No key with this keygrip\n"
 msgstr "No hi ha cap ID amb l'índex %d\n"
 
 #, fuzzy, c-format
+msgid "error reading the card: %s\n"
+msgstr "%s: error en llegir el registre lliure: %s\n"
+
+#, fuzzy, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "error en la creació de la contrasenya: %s\n"
+
+#, fuzzy
+msgid "Available keys:\n"
+msgstr "desactiva una clau"
+
+#, fuzzy, c-format
 #| msgid "rounded up to %u bits\n"
 msgid "rounded to %u bits\n"
 msgstr "arrodonida fins a %u bits\n"
@@ -5056,6 +5070,11 @@ msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "signatura %s, algorisme de resum %s\n"
 
 #, fuzzy, c-format
+#| msgid "%s signature, digest algorithm %s\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "signatura %s, algorisme de resum %s\n"
+
+#, fuzzy, c-format
 msgid "(reported error: %s)\n"
 msgstr "error de lectura: %s\n"
 
@@ -7257,18 +7276,6 @@ msgstr "   (%d) RSA (només xifrar)\n"
 msgid "   (%d) Existing key from card\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "error reading the card: %s\n"
-msgstr "%s: error en llegir el registre lliure: %s\n"
-
-#, fuzzy, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "error en la creació de la contrasenya: %s\n"
-
-#, fuzzy
-msgid "Available keys:\n"
-msgstr "desactiva una clau"
-
 #, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr ""
@@ -9380,6 +9387,15 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
+#~ msgid "male"
+#~ msgstr "home"
+
+#~ msgid "female"
+#~ msgstr "dóna"
+
+#~ msgid "unspecified"
+#~ msgstr "no especificat"
+
 #~ msgid "no keyserver known (use option --keyserver)\n"
 #~ msgstr "no es coneix cap servidor de claus (useu l'opció \"--keyserver\")\n"
 
index 532b977..cfa1b86 100644 (file)
--- a/po/cs.po
+++ b/po/cs.po
@@ -124,6 +124,7 @@ msgstr "neshodují se – zkuste to znovu"
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr "SETERROR %s (pokus %d z %d)"
@@ -1296,14 +1297,11 @@ msgstr "Váš výběr? "
 msgid "[not set]"
 msgstr "[není nastaveno]"
 
-msgid "male"
-msgstr "muž"
-
-msgid "female"
-msgstr "žena"
+msgid "Mr."
+msgstr ""
 
-msgid "unspecified"
-msgstr "neuvedeno"
+msgid "Ms."
+msgstr ""
 
 msgid "not forced"
 msgstr "není vyžadováno"
@@ -1356,8 +1354,8 @@ msgstr "Chyba: neplatná délka řetězce s předvolbami.\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "Chyba: neplatný znak v řetězci s předvolbami\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
-msgstr "Zadejte pohlaví: M – mužské, F – ženské, nebo stiskněte mezerník: "
+msgid "Salutation (M = Mr., F = Ms., or space): "
+msgstr ""
 
 msgid "Error: invalid response.\n"
 msgstr "Chyba: neplatná odpověď.\n"
@@ -1531,7 +1529,9 @@ msgstr "změnit login name"
 msgid "change the language preferences"
 msgstr "změnit jazykové předvolby"
 
-msgid "change card holder's sex"
+#, fuzzy
+#| msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr "změní pohlaví držitele karty"
 
 msgid "change a CA fingerprint"
@@ -3861,14 +3861,14 @@ msgid "Authenticate"
 msgstr "Autentizace"
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr "SsEeAaQq"
@@ -3948,6 +3948,11 @@ msgstr "  (%d) ECC (pouze pro šifrování)\n"
 msgid "  (%d) Existing key\n"
 msgstr "  (%d) Existující klíč\n"
 
+#, fuzzy, c-format
+#| msgid "   (%d) Existing key from card\n"
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) Klíč existující na kartě\n"
+
 msgid "Enter the keygrip: "
 msgstr "Vložte keygrip: "
 
@@ -3958,6 +3963,17 @@ msgid "No key with this keygrip\n"
 msgstr "Klíč s takovým keygripem neexistuje\n"
 
 #, c-format
+msgid "error reading the card: %s\n"
+msgstr "chyba při čtení z karty: %s\n"
+
+#, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "Sériové číslo karty: %s\n"
+
+msgid "Available keys:\n"
+msgstr "Dostupné klíče:\n"
+
+#, c-format
 msgid "rounded to %u bits\n"
 msgstr "zaokrouhleno na %u bitů\n"
 
@@ -4687,6 +4703,11 @@ msgstr "VAROVÁNÍ: vyžádaný algoritmus %s není doporučen\n"
 msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "Poznámka: podpisy používající algoritmus %s jsou zamítány\n"
 
+#, fuzzy, c-format
+#| msgid "Note: signatures using the %s algorithm are rejected\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "Poznámka: podpisy používající algoritmus %s jsou zamítány\n"
+
 #, c-format
 msgid "(reported error: %s)\n"
 msgstr "(nahlášená chyba: %s)\n"
@@ -6837,17 +6858,6 @@ msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) Klíč existující na kartě\n"
 
 #, c-format
-msgid "error reading the card: %s\n"
-msgstr "chyba při čtení z karty: %s\n"
-
-#, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "Sériové číslo karty: %s\n"
-
-msgid "Available keys:\n"
-msgstr "Dostupné klíče:\n"
-
-#, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr "Možné způsoby užití %s klíče:\n"
 
@@ -8882,6 +8892,18 @@ msgstr ""
 "Syntaxe: gpg-check-pattern [volby] soubor_se_vzorem\n"
 "Prověří heslo zadané na vstupu proti souboru se vzory\n"
 
+#~ msgid "male"
+#~ msgstr "muž"
+
+#~ msgid "female"
+#~ msgstr "žena"
+
+#~ msgid "unspecified"
+#~ msgstr "neuvedeno"
+
+#~ msgid "Sex ((M)ale, (F)emale or space): "
+#~ msgstr "Zadejte pohlaví: M – mužské, F – ženské, nebo stiskněte mezerník: "
+
 #~ msgid "no keyserver known (use option --keyserver)\n"
 #~ msgstr "žádný server klíčů není znám (použijte volbu --keyserver)\n"
 
index 8b04072..2a4e57e 100644 (file)
--- a/po/da.po
+++ b/po/da.po
@@ -115,6 +115,7 @@ msgstr "matcher ikke - prøv igen"
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr "SETERROR %s (forsøg %d af %d)"
@@ -1388,14 +1389,11 @@ msgstr "Dit valg? "
 msgid "[not set]"
 msgstr "[ikke indstillet]"
 
-msgid "male"
-msgstr "mand"
-
-msgid "female"
-msgstr "kvinde"
+msgid "Mr."
+msgstr ""
 
-msgid "unspecified"
-msgstr "ikke angivet"
+msgid "Ms."
+msgstr ""
 
 msgid "not forced"
 msgstr "ikke tvunget"
@@ -1450,8 +1448,8 @@ msgstr "Fejl: ugyldig længde for præferencestreng.\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "Fejl: ugyldige tegn i præferencestreng.\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
-msgstr "Køn ((M)and, Kvinde(F) eller mellemrum): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
+msgstr ""
 
 msgid "Error: invalid response.\n"
 msgstr "Fejl: ugyldigt svar.\n"
@@ -1646,7 +1644,9 @@ msgstr "ændr logindnavnet"
 msgid "change the language preferences"
 msgstr "ændr sprogpræferencerne"
 
-msgid "change card holder's sex"
+#, fuzzy
+#| msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr "ændr kortholders køn"
 
 msgid "change a CA fingerprint"
@@ -4139,14 +4139,14 @@ msgid "Authenticate"
 msgstr "Godkend"
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr "UuKkGfAa"
@@ -4231,6 +4231,11 @@ msgstr "   (%d) RSA (kun krypter)\n"
 msgid "  (%d) Existing key\n"
 msgstr "   (%d) Eksisterende nøgle\n"
 
+#, fuzzy, c-format
+#| msgid "   (%d) Existing key from card\n"
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) Eksisterende nøgle fra kort\n"
+
 # key grip
 # chiefly  ( US ) See also grip the person in charge of moving and setting up camera
 # tracks and scenery in a film or television studio
@@ -4243,6 +4248,17 @@ msgstr "Ikke et gyldigt nøglegreb (forventer 40 hex cifre)\n"
 msgid "No key with this keygrip\n"
 msgstr "Ingen nøgle med dette nøglegreb\n"
 
+#, c-format
+msgid "error reading the card: %s\n"
+msgstr "fejl ved læsning af kort: %s\n"
+
+#, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "Serielnummer for kortet: %s\n"
+
+msgid "Available keys:\n"
+msgstr "Tilgængelige nøgler:\n"
+
 #, fuzzy, c-format
 #| msgid "rounded up to %u bits\n"
 msgid "rounded to %u bits\n"
@@ -4989,6 +5005,11 @@ msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "%s underskrift, sammendragsalgoritme %s\n"
 
 #, fuzzy, c-format
+#| msgid "%s signature, digest algorithm %s\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "%s underskrift, sammendragsalgoritme %s\n"
+
+#, fuzzy, c-format
 #| msgid "read error in `%s': %s\n"
 msgid "(reported error: %s)\n"
 msgstr "læsefejl i »%s«: %s\n"
@@ -7205,17 +7226,6 @@ msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) Eksisterende nøgle fra kort\n"
 
 #, c-format
-msgid "error reading the card: %s\n"
-msgstr "fejl ved læsning af kort: %s\n"
-
-#, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "Serielnummer for kortet: %s\n"
-
-msgid "Available keys:\n"
-msgstr "Tilgængelige nøgler:\n"
-
-#, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr "Mulige handlinger for en %s-nøgle:\n"
 
@@ -9503,6 +9513,18 @@ msgstr ""
 "Syntaks: gpg-check-pattern [tilvalg] mønsterfil\n"
 "Kontroller en adgangsfrase angivet på stdin mod mønsterfilen\n"
 
+#~ msgid "male"
+#~ msgstr "mand"
+
+#~ msgid "female"
+#~ msgstr "kvinde"
+
+#~ msgid "unspecified"
+#~ msgstr "ikke angivet"
+
+#~ msgid "Sex ((M)ale, (F)emale or space): "
+#~ msgstr "Køn ((M)and, Kvinde(F) eller mellemrum): "
+
 #~ msgid "no keyserver known (use option --keyserver)\n"
 #~ msgstr "ingen kendt nøgleserver (brug tilvalget --keyserver)\n"
 
index a3c1147..f7bd367 100644 (file)
--- 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: 2019-07-09 13:31+0200\n"
+"PO-Revision-Date: 2019-11-25 16:24+0100\n"
 "Last-Translator: Werner Koch <wk@gnupg.org>\n"
 "Language-Team: German <de@li.org>\n"
 "Language: de\n"
@@ -100,6 +100,7 @@ msgstr "Keine Übereinstimmung - bitte nochmal versuchen."
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr "SETERROR %s (Versuch %d von %d)"
@@ -1293,14 +1294,11 @@ msgstr "Ihre Auswahl? "
 msgid "[not set]"
 msgstr "[nicht gesetzt]"
 
-msgid "male"
-msgstr "männlich"
+msgid "Mr."
+msgstr "Hr."
 
-msgid "female"
-msgstr "weiblich"
-
-msgid "unspecified"
-msgstr "unbestimmt"
+msgid "Ms."
+msgstr "Fr."
 
 msgid "not forced"
 msgstr "nicht zwingend"
@@ -1354,8 +1352,8 @@ msgstr "Fehler: Ungültige Länge der Einstellungs-Zeichenfolge.\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "Fehler: Ungültige Zeichen in der Einstellungs-Zeichenfolge\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
-msgstr "Geschlecht: (Männlich (M), Weiblich (F) oder Leerzeichen): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
+msgstr "Anrede (M=Hr., F=Fr. oder Leerzeichen): "
 
 msgid "Error: invalid response.\n"
 msgstr "Fehler: ungültige Antwort.\n"
@@ -1534,8 +1532,8 @@ msgstr "Ändern der Logindaten"
 msgid "change the language preferences"
 msgstr "Ändern der Spracheinstellungen"
 
-msgid "change card holder's sex"
-msgstr "Ändern des Geschlechts des Kartenbesitzers"
+msgid "change card holder's salutation"
+msgstr "Ändern der Anrede des Kartenbesitzers"
 
 msgid "change a CA fingerprint"
 msgstr "Ändern des CA-Fingerabdrucks"
@@ -3916,14 +3914,14 @@ msgid "Authenticate"
 msgstr "Authentisierung"
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr "SsVvAaQq"
@@ -4003,6 +4001,10 @@ msgstr "  (%d) ECC (nur verschlüsseln)\n"
 msgid "  (%d) Existing key\n"
 msgstr "   (%d) Vorhandener Schlüssel\n"
 
+#, c-format
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) Vorhandener Schlüssel auf der Karte\n"
+
 msgid "Enter the keygrip: "
 msgstr "Geben Sie den \"Keygrip\" ein: "
 
@@ -4013,6 +4015,17 @@ msgid "No key with this keygrip\n"
 msgstr "Kein Schlüssel mit diesem \"Keygrip\"\n"
 
 #, c-format
+msgid "error reading the card: %s\n"
+msgstr "Fehler beim Lesen von der Karte: %s\n"
+
+#, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "Karten-Seriennummer: %s\n"
+
+msgid "Available keys:\n"
+msgstr "Vorhandene Schlüssel:\n"
+
+#, c-format
 msgid "rounded to %u bits\n"
 msgstr "gerundet auf %u Bit\n"
 
@@ -4735,6 +4748,12 @@ msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "Hinweis: %s basierte Signaturen werden zurückgewiesen.\n"
 
 #, c-format
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr ""
+"Hinweis: Beglaubigungen von Dritten basierend auf dem %s Algorithmus werden "
+"zurückgewiesen.\n"
+
+#, c-format
 msgid "(reported error: %s)\n"
 msgstr "(gemeldeter Fehler: %s)\n"
 
@@ -6948,17 +6967,6 @@ msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) Vorhandener Schlüssel auf der Karte\n"
 
 #, c-format
-msgid "error reading the card: %s\n"
-msgstr "Fehler beim Lesen von der Karte: %s\n"
-
-#, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "Karten-Seriennummer: %s\n"
-
-msgid "Available keys:\n"
-msgstr "Vorhandene Schlüssel:\n"
-
-#, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr "Mögliche Vorgänge eines %s-Schlüssels:\n"
 
@@ -9021,6 +9029,18 @@ msgstr ""
 "Syntax: gpg-check-pattern [optionen] Musterdatei\n"
 "Die von stdin gelesene Passphrase gegen die Musterdatei prüfen\n"
 
+#~ msgid "male"
+#~ msgstr "männlich"
+
+#~ msgid "female"
+#~ msgstr "weiblich"
+
+#~ msgid "unspecified"
+#~ msgstr "unbestimmt"
+
+#~ msgid "Sex ((M)ale, (F)emale or space): "
+#~ msgstr "Geschlecht: (Männlich (M), Weiblich (F) oder Leerzeichen): "
+
 #, fuzzy
 #~| msgid "error writing public keyring '%s': %s\n"
 #~ msgid "error setting policy for key %s, user id \"%s\": %s"
index 775ccb2..7303b06 100644 (file)
--- a/po/el.po
+++ b/po/el.po
@@ -95,6 +95,7 @@ msgstr ""
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -1334,17 +1335,11 @@ msgstr "Η επιλογή σας; "
 msgid "[not set]"
 msgstr ""
 
-#, fuzzy
-msgid "male"
-msgstr "enable"
-
-#, fuzzy
-msgid "female"
-msgstr "enable"
+msgid "Mr."
+msgstr ""
 
-#, fuzzy
-msgid "unspecified"
-msgstr "Δεν έχει οριστεί αιτία"
+msgid "Ms."
+msgstr ""
 
 #, fuzzy
 msgid "not forced"
@@ -1403,7 +1398,7 @@ msgstr "μη έγκυρος χαρακτήρας στο \"κορδόνι\" τη
 msgid "Error: invalid characters in preference string.\n"
 msgstr "μη έγκυρος χαρακτήρας στο \"κορδόνι\" της επιλογής\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
 msgstr ""
 
 #, fuzzy
@@ -1586,7 +1581,7 @@ msgstr "αλλαγή της ημερομηνίας λήξης"
 msgid "change the language preferences"
 msgstr "αλλαγή της εμπιστοσύνης ιδιοκτήτη"
 
-msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr ""
 
 #, fuzzy
@@ -4103,14 +4098,14 @@ msgid "Authenticate"
 msgstr ""
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr ""
@@ -4192,6 +4187,10 @@ msgstr "   (%d) RSA (για κρυπτογράφηση μόνο)\n"
 msgid "  (%d) Existing key\n"
 msgstr "   (%d) RSA (για κρυπτογράφηση μόνο)\n"
 
+#, fuzzy, c-format
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) RSA (για κρυπτογράφηση μόνο)\n"
+
 #, fuzzy
 msgid "Enter the keygrip: "
 msgstr "Σημείωση υπογραφής: "
@@ -4204,6 +4203,18 @@ msgid "No key with this keygrip\n"
 msgstr "Δεν υπάρχει user ID με δείκτη %d\n"
 
 #, fuzzy, c-format
+msgid "error reading the card: %s\n"
+msgstr "%s: σφάλμα στην ανάγνωση της εγγραφής free : %s\n"
+
+#, fuzzy, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "σφάλμα στη δημιουργία της φράσης κλειδί: %s\n"
+
+#, fuzzy
+msgid "Available keys:\n"
+msgstr "απενεργοποιεί ένα κλειδί"
+
+#, fuzzy, c-format
 #| msgid "rounded up to %u bits\n"
 msgid "rounded to %u bits\n"
 msgstr "στρογγυλοποιήθηκε έως τα %u bits\n"
@@ -4953,6 +4964,11 @@ msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "%s υπογραφή, αλγόριθμος περίληψης %s\n"
 
 #, fuzzy, c-format
+#| msgid "%s signature, digest algorithm %s\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "%s υπογραφή, αλγόριθμος περίληψης %s\n"
+
+#, fuzzy, c-format
 msgid "(reported error: %s)\n"
 msgstr "σφάλμα ανάγνωσης: %s\n"
 
@@ -7108,18 +7124,6 @@ msgstr "   (%d) RSA (για κρυπτογράφηση μόνο)\n"
 msgid "   (%d) Existing key from card\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "error reading the card: %s\n"
-msgstr "%s: σφάλμα στην ανάγνωση της εγγραφής free : %s\n"
-
-#, fuzzy, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "σφάλμα στη δημιουργία της φράσης κλειδί: %s\n"
-
-#, fuzzy
-msgid "Available keys:\n"
-msgstr "απενεργοποιεί ένα κλειδί"
-
 #, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr ""
@@ -9214,6 +9218,18 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "male"
+#~ msgstr "enable"
+
+#, fuzzy
+#~ msgid "female"
+#~ msgstr "enable"
+
+#, fuzzy
+#~ msgid "unspecified"
+#~ msgstr "Δεν έχει οριστεί αιτία"
+
+#, fuzzy
 #~ msgid "error creating 'ultimately_trusted_keys' TOFU table: %s\n"
 #~ msgstr "σφάλμα στη δημιουργία της φράσης κλειδί: %s\n"
 
index afe624f..61cba2f 100644 (file)
--- a/po/eo.po
+++ b/po/eo.po
@@ -95,6 +95,7 @@ msgstr ""
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -1334,17 +1335,11 @@ msgstr "Via elekto? "
 msgid "[not set]"
 msgstr ""
 
-#, fuzzy
-msgid "male"
-msgstr "en"
-
-#, fuzzy
-msgid "female"
-msgstr "en"
+msgid "Mr."
+msgstr ""
 
-#, fuzzy
-msgid "unspecified"
-msgstr "Nenia kialo specifita"
+msgid "Ms."
+msgstr ""
 
 #, fuzzy
 msgid "not forced"
@@ -1403,7 +1398,7 @@ msgstr "nevalida signo en signoĉeno\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "nevalida signo en signoĉeno\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
 msgstr ""
 
 #, fuzzy
@@ -1586,7 +1581,7 @@ msgstr "ŝanĝi la daton de eksvalidiĝo"
 msgid "change the language preferences"
 msgstr "ŝanĝi la posedantofidon"
 
-msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr ""
 
 #, fuzzy
@@ -4064,14 +4059,14 @@ msgid "Authenticate"
 msgstr ""
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr ""
@@ -4153,6 +4148,10 @@ msgstr "   (%d) RSA (nur ĉifri)\n"
 msgid "  (%d) Existing key\n"
 msgstr "   (%d) RSA (nur ĉifri)\n"
 
+#, fuzzy, c-format
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) RSA (nur ĉifri)\n"
+
 #, fuzzy
 msgid "Enter the keygrip: "
 msgstr "Subskribo-notacio: "
@@ -4165,6 +4164,18 @@ msgid "No key with this keygrip\n"
 msgstr "Mankas uzantidentigilo kun indekso %d\n"
 
 #, fuzzy, c-format
+msgid "error reading the card: %s\n"
+msgstr "%s: eraro dum legado de libera registro: %s\n"
+
+#, fuzzy, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "eraro dum kreado de pasfrazo: %s\n"
+
+#, fuzzy
+msgid "Available keys:\n"
+msgstr "malŝalti ŝlosilon"
+
+#, fuzzy, c-format
 #| msgid "rounded up to %u bits\n"
 msgid "rounded to %u bits\n"
 msgstr "rondigita ĝis %u bitoj\n"
@@ -4907,6 +4918,10 @@ msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "%s-subskribo de: %s\n"
 
 #, fuzzy, c-format
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "%s-subskribo de: %s\n"
+
+#, fuzzy, c-format
 msgid "(reported error: %s)\n"
 msgstr "kiraso: %s\n"
 
@@ -7032,18 +7047,6 @@ msgstr "   (%d) RSA (nur ĉifri)\n"
 msgid "   (%d) Existing key from card\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "error reading the card: %s\n"
-msgstr "%s: eraro dum legado de libera registro: %s\n"
-
-#, fuzzy, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "eraro dum kreado de pasfrazo: %s\n"
-
-#, fuzzy
-msgid "Available keys:\n"
-msgstr "malŝalti ŝlosilon"
-
 #, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr ""
@@ -9129,6 +9132,18 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
+#, fuzzy
+#~ msgid "male"
+#~ msgstr "en"
+
+#, fuzzy
+#~ msgid "female"
+#~ msgstr "en"
+
+#, fuzzy
+#~ msgid "unspecified"
+#~ msgstr "Nenia kialo specifita"
+
 #~ msgid "no keyserver known (use option --keyserver)\n"
 #~ msgstr "neniu ŝlosilservilo konata (uzu la opcion --keyserver)\n"
 
index b73819e..5d8881a 100644 (file)
--- a/po/es.po
+++ b/po/es.po
@@ -105,6 +105,7 @@ msgstr "no coincide - reinténtelo"
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr "SETERROR %s (intento %d de %d)"
@@ -1299,14 +1300,11 @@ msgstr "Su elección: "
 msgid "[not set]"
 msgstr "[no establecido]"
 
-msgid "male"
-msgstr "hombre"
-
-msgid "female"
-msgstr "mujer"
+msgid "Mr."
+msgstr ""
 
-msgid "unspecified"
-msgstr "no especificado"
+msgid "Ms."
+msgstr ""
 
 msgid "not forced"
 msgstr "no forzado"
@@ -1359,8 +1357,8 @@ msgstr "Error: longitud de la cadena de preferencias inválida.\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "Error: caracteres inválidos en cadena de preferencias.\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
-msgstr "Sexo ((H)ombre, (M)mujer o espacio): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
+msgstr ""
 
 msgid "Error: invalid response.\n"
 msgstr "Error: respuesta no válida.\n"
@@ -1534,7 +1532,9 @@ msgstr "cambiar nombre de usuario"
 msgid "change the language preferences"
 msgstr "cambiar preferencias de idioma"
 
-msgid "change card holder's sex"
+#, fuzzy
+#| msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr "cambiar sexo del titular de la tarjeta"
 
 msgid "change a CA fingerprint"
@@ -3860,14 +3860,14 @@ msgid "Authenticate"
 msgstr "Autentificación"
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr "FfCcAaSs"
@@ -3947,6 +3947,11 @@ msgstr "   (%d) ECC (sólo cifrar)\n"
 msgid "  (%d) Existing key\n"
 msgstr "   (%d) Clave existente\n"
 
+#, fuzzy, c-format
+#| msgid "   (%d) Existing key from card\n"
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) Clave existente de la tarjeta\n"
+
 msgid "Enter the keygrip: "
 msgstr "Introduzca keygrip: "
 
@@ -3957,6 +3962,17 @@ msgid "No key with this keygrip\n"
 msgstr "No hay claves con ese keygrip\n"
 
 #, c-format
+msgid "error reading the card: %s\n"
+msgstr "error al leer la tarjeta: %s\n"
+
+#, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "Número de serie de la tarjeta: %s\n"
+
+msgid "Available keys:\n"
+msgstr "Claves disponibles:\n"
+
+#, c-format
 msgid "rounded to %u bits\n"
 msgstr "redondeados a %u bits\n"
 
@@ -4672,6 +4688,11 @@ msgstr "AVISO: el algoritmo de resumen %s está obsoleto\n"
 msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "Atención: las firmas que usan el algoritmo %s son rechazadas\n"
 
+#, fuzzy, c-format
+#| msgid "Note: signatures using the %s algorithm are rejected\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "Atención: las firmas que usan el algoritmo %s son rechazadas\n"
+
 #, c-format
 msgid "(reported error: %s)\n"
 msgstr "(error reportado: %s)\n"
@@ -6819,17 +6840,6 @@ msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) Clave existente de la tarjeta\n"
 
 #, c-format
-msgid "error reading the card: %s\n"
-msgstr "error al leer la tarjeta: %s\n"
-
-#, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "Número de serie de la tarjeta: %s\n"
-
-msgid "Available keys:\n"
-msgstr "Claves disponibles:\n"
-
-#, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr "Posibles acciones para una clave %s:\n"
 
@@ -8891,6 +8901,18 @@ msgstr ""
 "Compara frase contraseña dada en entrada estándar con un fichero de "
 "patrones\n"
 
+#~ msgid "male"
+#~ msgstr "hombre"
+
+#~ msgid "female"
+#~ msgstr "mujer"
+
+#~ msgid "unspecified"
+#~ msgstr "no especificado"
+
+#~ msgid "Sex ((M)ale, (F)emale or space): "
+#~ msgstr "Sexo ((H)ombre, (M)mujer o espacio): "
+
 #~ msgid "no keyserver known (use option --keyserver)\n"
 #~ msgstr "no hay servidores de claves conocidos (use opción --keyserver)\n"
 
index ea5ca92..5753a73 100644 (file)
--- a/po/et.po
+++ b/po/et.po
@@ -92,6 +92,7 @@ msgstr ""
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -1330,17 +1331,11 @@ msgstr "Teie valik? "
 msgid "[not set]"
 msgstr ""
 
-#, fuzzy
-msgid "male"
-msgstr "enable"
-
-#, fuzzy
-msgid "female"
-msgstr "enable"
+msgid "Mr."
+msgstr ""
 
-#, fuzzy
-msgid "unspecified"
-msgstr "Põhjus puudub"
+msgid "Ms."
+msgstr ""
 
 #, fuzzy
 msgid "not forced"
@@ -1399,7 +1394,7 @@ msgstr "lubamatu sümbol eelistuste sõnes\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "lubamatu sümbol eelistuste sõnes\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
 msgstr ""
 
 #, fuzzy
@@ -1582,7 +1577,7 @@ msgstr "muuda aegumise kuupäeva"
 msgid "change the language preferences"
 msgstr "muuda omaniku usaldust"
 
-msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr ""
 
 #, fuzzy
@@ -4063,14 +4058,14 @@ msgid "Authenticate"
 msgstr ""
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr ""
@@ -4152,6 +4147,10 @@ msgstr "   (%d) RSA (ainult krüpteerimiseks)\n"
 msgid "  (%d) Existing key\n"
 msgstr "   (%d) RSA (ainult krüpteerimiseks)\n"
 
+#, fuzzy, c-format
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) RSA (ainult krüpteerimiseks)\n"
+
 #, fuzzy
 msgid "Enter the keygrip: "
 msgstr "Allkirja noteerimine: "
@@ -4164,6 +4163,18 @@ msgid "No key with this keygrip\n"
 msgstr "Kasutaja ID numbriga %d puudub\n"
 
 #, fuzzy, c-format
+msgid "error reading the card: %s\n"
+msgstr "%s: viga vaba kirje lugemisel: %s\n"
+
+#, fuzzy, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "viga parooli loomisel: %s\n"
+
+#, fuzzy
+msgid "Available keys:\n"
+msgstr "blokeeri võti"
+
+#, fuzzy, c-format
 #| msgid "rounded up to %u bits\n"
 msgid "rounded to %u bits\n"
 msgstr "ümardatud üles %u bitini\n"
@@ -4898,6 +4909,11 @@ msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "%s allkiri, sõnumilühendi algoritm %s\n"
 
 #, fuzzy, c-format
+#| msgid "%s signature, digest algorithm %s\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "%s allkiri, sõnumilühendi algoritm %s\n"
+
+#, fuzzy, c-format
 msgid "(reported error: %s)\n"
 msgstr "viga lugemisel: %s\n"
 
@@ -7028,18 +7044,6 @@ msgstr "   (%d) RSA (ainult krüpteerimiseks)\n"
 msgid "   (%d) Existing key from card\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "error reading the card: %s\n"
-msgstr "%s: viga vaba kirje lugemisel: %s\n"
-
-#, fuzzy, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "viga parooli loomisel: %s\n"
-
-#, fuzzy
-msgid "Available keys:\n"
-msgstr "blokeeri võti"
-
 #, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr ""
@@ -9130,6 +9134,18 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "male"
+#~ msgstr "enable"
+
+#, fuzzy
+#~ msgid "female"
+#~ msgstr "enable"
+
+#, fuzzy
+#~ msgid "unspecified"
+#~ msgstr "Põhjus puudub"
+
+#, fuzzy
 #~ msgid "error creating 'ultimately_trusted_keys' TOFU table: %s\n"
 #~ msgstr "viga parooli loomisel: %s\n"
 
index 90be315..9823b8a 100644 (file)
--- a/po/fi.po
+++ b/po/fi.po
@@ -108,6 +108,7 @@ msgstr ""
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -1349,17 +1350,11 @@ msgstr "Valintasi? "
 msgid "[not set]"
 msgstr ""
 
-#, fuzzy
-msgid "male"
-msgstr "enable"
-
-#, fuzzy
-msgid "female"
-msgstr "enable"
+msgid "Mr."
+msgstr ""
 
-#, fuzzy
-msgid "unspecified"
-msgstr "Ei eriteltyä syytä"
+msgid "Ms."
+msgstr ""
 
 #, fuzzy
 msgid "not forced"
@@ -1418,7 +1413,7 @@ msgstr "Valinnassa on luvaton merkki\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "Valinnassa on luvaton merkki\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
 msgstr ""
 
 #, fuzzy
@@ -1601,7 +1596,7 @@ msgstr "muuta voimassoloaikaa"
 msgid "change the language preferences"
 msgstr "muuta luottamusastetta"
 
-msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr ""
 
 #, fuzzy
@@ -4088,14 +4083,14 @@ msgid "Authenticate"
 msgstr ""
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr ""
@@ -4177,6 +4172,10 @@ msgstr "   (%d) RSA (vain salaus)\n"
 msgid "  (%d) Existing key\n"
 msgstr "   (%d) RSA (vain salaus)\n"
 
+#, fuzzy, c-format
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) RSA (vain salaus)\n"
+
 #, fuzzy
 msgid "Enter the keygrip: "
 msgstr "Allekirjoitusnotaatio: "
@@ -4189,6 +4188,18 @@ msgid "No key with this keygrip\n"
 msgstr "Indeksillä %d ei löydy käyttäjätunnusta\n"
 
 #, fuzzy, c-format
+msgid "error reading the card: %s\n"
+msgstr "%s: virhe luettaessa vapaata tietuetta: %s\n"
+
+#, fuzzy, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "virhe luotaessa salasanaa: %s\n"
+
+#, fuzzy
+msgid "Available keys:\n"
+msgstr "poista avain käytöstä"
+
+#, fuzzy, c-format
 #| msgid "rounded up to %u bits\n"
 msgid "rounded to %u bits\n"
 msgstr "pyöristetty %u bittiin\n"
@@ -4936,6 +4947,12 @@ msgstr ""
 msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "%sallekirjoitus, tiivistealgoritmi %s\n"
 
+# Ensimmäinen %s on binary, textmode tai unknown, ks. alla
+#, fuzzy, c-format
+#| msgid "%s signature, digest algorithm %s\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "%sallekirjoitus, tiivistealgoritmi %s\n"
+
 #, fuzzy, c-format
 msgid "(reported error: %s)\n"
 msgstr "lukuvirhe: %s\n"
@@ -7087,18 +7104,6 @@ msgstr "   (%d) RSA (vain salaus)\n"
 msgid "   (%d) Existing key from card\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "error reading the card: %s\n"
-msgstr "%s: virhe luettaessa vapaata tietuetta: %s\n"
-
-#, fuzzy, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "virhe luotaessa salasanaa: %s\n"
-
-#, fuzzy
-msgid "Available keys:\n"
-msgstr "poista avain käytöstä"
-
 #, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr ""
@@ -9192,6 +9197,18 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "male"
+#~ msgstr "enable"
+
+#, fuzzy
+#~ msgid "female"
+#~ msgstr "enable"
+
+#, fuzzy
+#~ msgid "unspecified"
+#~ msgstr "Ei eriteltyä syytä"
+
+#, fuzzy
 #~ msgid "error creating 'ultimately_trusted_keys' TOFU table: %s\n"
 #~ msgstr "virhe luotaessa salasanaa: %s\n"
 
index 3fea7e9..b0ae0b9 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -107,6 +107,7 @@ msgstr "ne correspond pas — veuillez réessayer"
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr "SETERROR %s (essai %d sur %d)"
@@ -1322,14 +1323,11 @@ msgstr "Quel est votre choix ? "
 msgid "[not set]"
 msgstr "[non positionné]"
 
-msgid "male"
-msgstr "masculin"
-
-msgid "female"
-msgstr "féminin"
+msgid "Mr."
+msgstr ""
 
-msgid "unspecified"
-msgstr "non indiqué"
+msgid "Ms."
+msgstr ""
 
 msgid "not forced"
 msgstr "non forcé"
@@ -1382,8 +1380,8 @@ msgstr "Erreur : taille incorrecte de la chaîne de préférences.\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "Erreur : caractères incorrects dans la chaîne de préférences.\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
-msgstr "Sexe ((M)asculin, (F)éminin ou espace) : "
+msgid "Salutation (M = Mr., F = Ms., or space): "
+msgstr ""
 
 msgid "Error: invalid response.\n"
 msgstr "Erreur : réponse incorrecte.\n"
@@ -1576,7 +1574,9 @@ msgstr "modifier l'identifiant de connexion"
 msgid "change the language preferences"
 msgstr "modifier les préférences de langue"
 
-msgid "change card holder's sex"
+#, fuzzy
+#| msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr "modifier le sexe du détenteur de la carte"
 
 msgid "change a CA fingerprint"
@@ -4026,14 +4026,14 @@ msgid "Authenticate"
 msgstr "Authentifier"
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr "SsCcAaQq"
@@ -4113,6 +4113,11 @@ msgstr "  (%d) ECC (chiffrement seul)\n"
 msgid "  (%d) Existing key\n"
 msgstr "  (%d) Clef existante\n"
 
+#, fuzzy, c-format
+#| msgid "   (%d) Existing key from card\n"
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) Clef existante sur la carte\n"
+
 msgid "Enter the keygrip: "
 msgstr "Entrez le keygrip : "
 
@@ -4123,6 +4128,17 @@ msgid "No key with this keygrip\n"
 msgstr "Pas de clef avec ce keygrip\n"
 
 #, c-format
+msgid "error reading the card: %s\n"
+msgstr "erreur de lecture de la carte : %s\n"
+
+#, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "Numéro de série de la carte : %s\n"
+
+msgid "Available keys:\n"
+msgstr "Clefs disponibles :\n"
+
+#, c-format
 msgid "rounded to %u bits\n"
 msgstr "arrondie à %u bits\n"
 
@@ -4870,6 +4886,11 @@ msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "Remarque : les signatures utilisant l’algorithme %s sont rejetées\n"
 
 #, fuzzy, c-format
+#| msgid "Note: signatures using the %s algorithm are rejected\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "Remarque : les signatures utilisant l’algorithme %s sont rejetées\n"
+
+#, fuzzy, c-format
 #| msgid "%s:%u: read error: %s\n"
 msgid "(reported error: %s)\n"
 msgstr "%s : %u : erreur de lecture : %s\n"
@@ -7126,17 +7147,6 @@ msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) Clef existante sur la carte\n"
 
 #, c-format
-msgid "error reading the card: %s\n"
-msgstr "erreur de lecture de la carte : %s\n"
-
-#, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "Numéro de série de la carte : %s\n"
-
-msgid "Available keys:\n"
-msgstr "Clefs disponibles :\n"
-
-#, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr "Actions possibles pour une clef %s :\n"
 
@@ -9264,6 +9274,18 @@ msgstr ""
 "Vérifier une phrase secrète donnée sur l'entrée standard par rapport à "
 "ficmotif\n"
 
+#~ msgid "male"
+#~ msgstr "masculin"
+
+#~ msgid "female"
+#~ msgstr "féminin"
+
+#~ msgid "unspecified"
+#~ msgstr "non indiqué"
+
+#~ msgid "Sex ((M)ale, (F)emale or space): "
+#~ msgstr "Sexe ((M)asculin, (F)éminin ou espace) : "
+
 #~ msgid "no keyserver known (use option --keyserver)\n"
 #~ msgstr "pas de serveur de clefs connu (utilisez l'option --keyserver)\n"
 
index d555669..43b4881 100644 (file)
--- a/po/gl.po
+++ b/po/gl.po
@@ -93,6 +93,7 @@ msgstr ""
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -1339,17 +1340,11 @@ msgstr "¿A súa selección? "
 msgid "[not set]"
 msgstr ""
 
-#, fuzzy
-msgid "male"
-msgstr "enable"
-
-#, fuzzy
-msgid "female"
-msgstr "enable"
+msgid "Mr."
+msgstr ""
 
-#, fuzzy
-msgid "unspecified"
-msgstr "Non se especificou un motivo"
+msgid "Ms."
+msgstr ""
 
 #, fuzzy
 msgid "not forced"
@@ -1408,7 +1403,7 @@ msgstr "caracter non válido na cadea de preferencias\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "caracter non válido na cadea de preferencias\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
 msgstr ""
 
 #, fuzzy
@@ -1591,7 +1586,7 @@ msgstr "cambia-la fecha de expiración"
 msgid "change the language preferences"
 msgstr "cambia-la confianza sobre o dono"
 
-msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr ""
 
 #, fuzzy
@@ -4098,14 +4093,14 @@ msgid "Authenticate"
 msgstr ""
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr ""
@@ -4187,6 +4182,10 @@ msgstr "   (%d) RSA (só cifrar)\n"
 msgid "  (%d) Existing key\n"
 msgstr "   (%d) RSA (só cifrar)\n"
 
+#, fuzzy, c-format
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) RSA (só cifrar)\n"
+
 #, fuzzy
 msgid "Enter the keygrip: "
 msgstr "Notación de sinaturas: "
@@ -4199,6 +4198,18 @@ msgid "No key with this keygrip\n"
 msgstr "Non hai ID de usuario con índice %d\n"
 
 #, fuzzy, c-format
+msgid "error reading the card: %s\n"
+msgstr "%s: erro ao ler un rexistro libre: %s\n"
+
+#, fuzzy, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "erro ao crea-lo contrasinal: %s\n"
+
+#, fuzzy
+msgid "Available keys:\n"
+msgstr "deshabilitar unha chave"
+
+#, fuzzy, c-format
 #| msgid "rounded up to %u bits\n"
 msgid "rounded to %u bits\n"
 msgstr "redondeado a %u bits\n"
@@ -4945,6 +4956,11 @@ msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "Sinatura %s, algoritmo de resumo %s\n"
 
 #, fuzzy, c-format
+#| msgid "%s signature, digest algorithm %s\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "Sinatura %s, algoritmo de resumo %s\n"
+
+#, fuzzy, c-format
 msgid "(reported error: %s)\n"
 msgstr "erro de lectura: %s\n"
 
@@ -7099,18 +7115,6 @@ msgstr "   (%d) RSA (só cifrar)\n"
 msgid "   (%d) Existing key from card\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "error reading the card: %s\n"
-msgstr "%s: erro ao ler un rexistro libre: %s\n"
-
-#, fuzzy, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "erro ao crea-lo contrasinal: %s\n"
-
-#, fuzzy
-msgid "Available keys:\n"
-msgstr "deshabilitar unha chave"
-
 #, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr ""
@@ -9210,6 +9214,18 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
+#, fuzzy
+#~ msgid "male"
+#~ msgstr "enable"
+
+#, fuzzy
+#~ msgid "female"
+#~ msgstr "enable"
+
+#, fuzzy
+#~ msgid "unspecified"
+#~ msgstr "Non se especificou un motivo"
+
 #~ msgid "no keyserver known (use option --keyserver)\n"
 #~ msgstr ""
 #~ "non hai un servidor de chaves coñecido (empregue a opción --keyserver)\n"
index 8cbb4b1..e3cc928 100644 (file)
--- a/po/hu.po
+++ b/po/hu.po
@@ -92,6 +92,7 @@ msgstr ""
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -1330,17 +1331,11 @@ msgstr "Mit választ? "
 msgid "[not set]"
 msgstr ""
 
-#, fuzzy
-msgid "male"
-msgstr "enable"
-
-#, fuzzy
-msgid "female"
-msgstr "enable"
+msgid "Mr."
+msgstr ""
 
-#, fuzzy
-msgid "unspecified"
-msgstr "Nincs megadva ok."
+msgid "Ms."
+msgstr ""
 
 #, fuzzy
 msgid "not forced"
@@ -1399,7 +1394,7 @@ msgstr "Érvénytelen karakter a preferenciák között!\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "Érvénytelen karakter a preferenciák között!\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
 msgstr ""
 
 #, fuzzy
@@ -1582,7 +1577,7 @@ msgstr "lejárat megváltoztatása"
 msgid "change the language preferences"
 msgstr "kulcstulajdonos megbízhatóságának beállítása"
 
-msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr ""
 
 #, fuzzy
@@ -4065,14 +4060,14 @@ msgid "Authenticate"
 msgstr ""
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr ""
@@ -4154,6 +4149,10 @@ msgstr "   (%d) RSA (csak titkosítás)\n"
 msgid "  (%d) Existing key\n"
 msgstr "   (%d) RSA (csak titkosítás)\n"
 
+#, fuzzy, c-format
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) RSA (csak titkosítás)\n"
+
 #, fuzzy
 msgid "Enter the keygrip: "
 msgstr "Aláírás-jelölés: "
@@ -4166,6 +4165,18 @@ msgid "No key with this keygrip\n"
 msgstr "Nincs %d indexű felhasználóazonosító!\n"
 
 #, fuzzy, c-format
+msgid "error reading the card: %s\n"
+msgstr "%s: Hiba szabad rekord olvasásakor: %s.\n"
+
+#, fuzzy, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "Hiba a jelszó létrehozásakor: %s.\n"
+
+#, fuzzy
+msgid "Available keys:\n"
+msgstr "kulcs tiltása"
+
+#, fuzzy, c-format
 #| msgid "rounded up to %u bits\n"
 msgid "rounded to %u bits\n"
 msgstr "Felkerekítve %u bitre.\n"
@@ -4915,6 +4926,11 @@ msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "%s aláírás, %s kivonatoló algoritmus.\n"
 
 #, fuzzy, c-format
+#| msgid "%s signature, digest algorithm %s\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "%s aláírás, %s kivonatoló algoritmus.\n"
+
+#, fuzzy, c-format
 msgid "(reported error: %s)\n"
 msgstr "Olvasási hiba: %s.\n"
 
@@ -7058,18 +7074,6 @@ msgstr "   (%d) RSA (csak titkosítás)\n"
 msgid "   (%d) Existing key from card\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "error reading the card: %s\n"
-msgstr "%s: Hiba szabad rekord olvasásakor: %s.\n"
-
-#, fuzzy, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "Hiba a jelszó létrehozásakor: %s.\n"
-
-#, fuzzy
-msgid "Available keys:\n"
-msgstr "kulcs tiltása"
-
 #, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr ""
@@ -9160,6 +9164,18 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "male"
+#~ msgstr "enable"
+
+#, fuzzy
+#~ msgid "female"
+#~ msgstr "enable"
+
+#, fuzzy
+#~ msgid "unspecified"
+#~ msgstr "Nincs megadva ok."
+
+#, fuzzy
 #~ msgid "error creating 'ultimately_trusted_keys' TOFU table: %s\n"
 #~ msgstr "Hiba a jelszó létrehozásakor: %s.\n"
 
index da18bfe..5451547 100644 (file)
--- a/po/id.po
+++ b/po/id.po
@@ -97,6 +97,7 @@ msgstr ""
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -1336,17 +1337,11 @@ msgstr "Pilihan anda? "
 msgid "[not set]"
 msgstr ""
 
-#, fuzzy
-msgid "male"
-msgstr "enable"
-
-#, fuzzy
-msgid "female"
-msgstr "enable"
+msgid "Mr."
+msgstr ""
 
-#, fuzzy
-msgid "unspecified"
-msgstr "Tidak ada alasan diberikan"
+msgid "Ms."
+msgstr ""
 
 #, fuzzy
 msgid "not forced"
@@ -1405,7 +1400,7 @@ msgstr "Karakter tidak valid dalam string preferensi\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "Karakter tidak valid dalam string preferensi\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
 msgstr ""
 
 #, fuzzy
@@ -1588,7 +1583,7 @@ msgstr "ubah tanggal kadaluarsa"
 msgid "change the language preferences"
 msgstr "ubah ownertrust"
 
-msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr ""
 
 #, fuzzy
@@ -4074,14 +4069,14 @@ msgid "Authenticate"
 msgstr ""
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr ""
@@ -4163,6 +4158,10 @@ msgstr "  (%d) RSA (hanya enkripsi)\n"
 msgid "  (%d) Existing key\n"
 msgstr "  (%d) RSA (hanya enkripsi)\n"
 
+#, fuzzy, c-format
+msgid "  (%d) Existing key from card\n"
+msgstr "  (%d) RSA (hanya enkripsi)\n"
+
 #, fuzzy
 msgid "Enter the keygrip: "
 msgstr "Notasi signature: "
@@ -4175,6 +4174,18 @@ msgid "No key with this keygrip\n"
 msgstr "Tidak ada ID user dengan index %d\n"
 
 #, fuzzy, c-format
+msgid "error reading the card: %s\n"
+msgstr "%s: kesalahan membaca record bebas: %s\n"
+
+#, fuzzy, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "kesalahan penciptaan passphrase: %s\n"
+
+#, fuzzy
+msgid "Available keys:\n"
+msgstr "tiadakan kunci"
+
+#, fuzzy, c-format
 #| msgid "rounded up to %u bits\n"
 msgid "rounded to %u bits\n"
 msgstr "dibulatkan hingga %u bit\n"
@@ -4912,6 +4923,11 @@ msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "%s signature, algoritma digest %s\n"
 
 #, fuzzy, c-format
+#| msgid "%s signature, digest algorithm %s\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "%s signature, algoritma digest %s\n"
+
+#, fuzzy, c-format
 msgid "(reported error: %s)\n"
 msgstr "kesalahan pembacaan: %s\n"
 
@@ -7050,18 +7066,6 @@ msgstr "  (%d) RSA (hanya enkripsi)\n"
 msgid "   (%d) Existing key from card\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "error reading the card: %s\n"
-msgstr "%s: kesalahan membaca record bebas: %s\n"
-
-#, fuzzy, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "kesalahan penciptaan passphrase: %s\n"
-
-#, fuzzy
-msgid "Available keys:\n"
-msgstr "tiadakan kunci"
-
 #, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr ""
@@ -9153,6 +9157,18 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "male"
+#~ msgstr "enable"
+
+#, fuzzy
+#~ msgid "female"
+#~ msgstr "enable"
+
+#, fuzzy
+#~ msgid "unspecified"
+#~ msgstr "Tidak ada alasan diberikan"
+
+#, fuzzy
 #~ msgid "error creating 'ultimately_trusted_keys' TOFU table: %s\n"
 #~ msgstr "kesalahan penciptaan passphrase: %s\n"
 
index eb35531..67d471c 100644 (file)
--- a/po/it.po
+++ b/po/it.po
@@ -92,6 +92,7 @@ msgstr ""
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -1333,17 +1334,11 @@ msgstr "Cosa scegli? "
 msgid "[not set]"
 msgstr ""
 
-#, fuzzy
-msgid "male"
-msgstr "abilita"
-
-#, fuzzy
-msgid "female"
-msgstr "abilita"
+msgid "Mr."
+msgstr ""
 
-#, fuzzy
-msgid "unspecified"
-msgstr "Nessuna ragione specificata"
+msgid "Ms."
+msgstr ""
 
 # ??? (Md)
 #, fuzzy
@@ -1403,7 +1398,7 @@ msgstr "carattere non valido nella stringa delle preferenze\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "carattere non valido nella stringa delle preferenze\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
 msgstr ""
 
 #, fuzzy
@@ -1586,7 +1581,7 @@ msgstr "cambia la data di scadenza"
 msgid "change the language preferences"
 msgstr "cambia il valore di fiducia"
 
-msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr ""
 
 #, fuzzy
@@ -4089,14 +4084,14 @@ msgid "Authenticate"
 msgstr ""
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr ""
@@ -4178,6 +4173,10 @@ msgstr "   (%d) RSA (cifra solo)\n"
 msgid "  (%d) Existing key\n"
 msgstr "   (%d) RSA (cifra solo)\n"
 
+#, fuzzy, c-format
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) RSA (cifra solo)\n"
+
 #, fuzzy
 msgid "Enter the keygrip: "
 msgstr "Annotazione della firma: "
@@ -4190,6 +4189,18 @@ msgid "No key with this keygrip\n"
 msgstr "Nessun user ID con l'indice %d\n"
 
 #, fuzzy, c-format
+msgid "error reading the card: %s\n"
+msgstr "%s: errore durante la lettura del record libero: %s\n"
+
+#, fuzzy, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "errore nella creazione della passhprase: %s\n"
+
+#, fuzzy
+msgid "Available keys:\n"
+msgstr "disabilita una chiave"
+
+#, fuzzy, c-format
 #| msgid "rounded up to %u bits\n"
 msgid "rounded to %u bits\n"
 msgstr "arrotondate a %u bit\n"
@@ -4930,6 +4941,11 @@ msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "Firma %s, algoritmo di digest %s\n"
 
 #, fuzzy, c-format
+#| msgid "%s signature, digest algorithm %s\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "Firma %s, algoritmo di digest %s\n"
+
+#, fuzzy, c-format
 msgid "(reported error: %s)\n"
 msgstr "errore di lettura: %s\n"
 
@@ -7089,18 +7105,6 @@ msgstr "   (%d) RSA (cifra solo)\n"
 msgid "   (%d) Existing key from card\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "error reading the card: %s\n"
-msgstr "%s: errore durante la lettura del record libero: %s\n"
-
-#, fuzzy, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "errore nella creazione della passhprase: %s\n"
-
-#, fuzzy
-msgid "Available keys:\n"
-msgstr "disabilita una chiave"
-
 #, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr ""
@@ -9194,6 +9198,18 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "male"
+#~ msgstr "abilita"
+
+#, fuzzy
+#~ msgid "female"
+#~ msgstr "abilita"
+
+#, fuzzy
+#~ msgid "unspecified"
+#~ msgstr "Nessuna ragione specificata"
+
+#, fuzzy
 #~ msgid "error creating 'ultimately_trusted_keys' TOFU table: %s\n"
 #~ msgstr "errore nella creazione della passhprase: %s\n"
 
index 3c3fc31..db4d998 100644 (file)
--- a/po/ja.po
+++ b/po/ja.po
@@ -4,13 +4,13 @@
 # IIDA Yosiaki <iida@gnu.org>, 1999, 2000, 2002, 2003, 2004.
 # Yoshihiro Kajiki <kajiki@ylug.org>, 1999.
 # Takashi P.KATOH, 2002.
-# NIIBE Yutaka <gniibe@fsij.org>, 2013, 2014, 2015, 2016, 2017, 2018.
+# NIIBE Yutaka <gniibe@fsij.org>, 2013, 2014, 2015, 2016, 2017, 2018, 2019.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: gnupg 2.2.15\n"
+"Project-Id-Version: gnupg 2.2.18\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2019-04-23 12:54+0900\n"
+"PO-Revision-Date: 2019-10-15 10:05+0900\n"
 "Last-Translator: NIIBE Yutaka <gniibe@fsij.org>\n"
 "Language-Team: none\n"
 "Language: ja\n"
@@ -96,6 +96,7 @@ msgstr "一致しません - もう一度"
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr "SETERROR %s (現在 %d / 最大 %d)"
@@ -1260,14 +1261,11 @@ msgstr "あなたの選択は? "
 msgid "[not set]"
 msgstr "[未設定]"
 
-msgid "male"
-msgstr "男"
-
-msgid "female"
-msgstr "女"
+msgid "Mr."
+msgstr ""
 
-msgid "unspecified"
-msgstr "無指定"
+msgid "Ms."
+msgstr ""
 
 msgid "not forced"
 msgstr "強制なし"
@@ -1320,8 +1318,8 @@ msgstr "エラー: 優先指定の文字列の長さが無効です。\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "エラー: 優先指定の文字列に無効な文字があります。\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
-msgstr "性別 ((M)男、(F)女、または空白): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
+msgstr ""
 
 msgid "Error: invalid response.\n"
 msgstr "エラー: 無効な応答。\n"
@@ -1494,7 +1492,9 @@ msgstr "ログイン名の変更"
 msgid "change the language preferences"
 msgstr "言語の優先指定の変更"
 
-msgid "change card holder's sex"
+#, fuzzy
+#| msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr "カード所有者の性別の変更"
 
 msgid "change a CA fingerprint"
@@ -1568,16 +1568,16 @@ msgid "can't do this in batch mode without \"--yes\"\n"
 msgstr "\"--yes\"なしでバッチ・モードではできません\n"
 
 msgid "Note: The public primary key and all its subkeys will be deleted.\n"
-msgstr ""
+msgstr "注意: 主鍵とすべての副鍵の公開鍵が削除されます。\n"
 
 msgid "Note: Only the shown public subkey will be deleted.\n"
-msgstr ""
+msgstr "注意: 表示されている副鍵の公開鍵だけが削除されます。\n"
 
 msgid "Note: Only the secret part of the shown primary key will be deleted.\n"
-msgstr ""
+msgstr "注意: 表示されている主鍵の秘密鍵だけが削除されます。\n"
 
 msgid "Note: Only the secret part of the shown subkey will be deleted.\n"
-msgstr ""
+msgstr "注意: 表示されている副鍵の秘密鍵だけが削除されます。\n"
 
 msgid "Delete this key from the keyring? (y/N) "
 msgstr "この鍵を鍵リングから削除しますか? (y/N) "
@@ -2509,7 +2509,7 @@ msgid "remove as much as possible from key after import"
 msgstr "インポート後、できるだけ除去します"
 
 msgid "ignore key-signatures which are not self-signatures"
-msgstr ""
+msgstr "自己署名ではない鍵への署名は無視します"
 
 msgid "run import filters and export key immediately"
 msgstr "インポート・フィルタを実行し鍵をすぐにエクスポートします"
@@ -3780,14 +3780,14 @@ msgid "Authenticate"
 msgstr "Authenticate"
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr "SsEeAaQq"
@@ -3867,6 +3867,11 @@ msgstr "  (%d) ECC (暗号化のみ)\n"
 msgid "  (%d) Existing key\n"
 msgstr "  (%d) 既存の鍵\n"
 
+#, fuzzy, c-format
+#| msgid "   (%d) Existing key from card\n"
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) カードに存在する鍵\n"
+
 msgid "Enter the keygrip: "
 msgstr "keygripを入力: "
 
@@ -3877,6 +3882,17 @@ msgid "No key with this keygrip\n"
 msgstr "このkeygripの鍵はありません\n"
 
 #, c-format
+msgid "error reading the card: %s\n"
+msgstr "カードの読み込みエラー: %s\n"
+
+#, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "カードのシリアル番号: %s\n"
+
+msgid "Available keys:\n"
+msgstr "利用可能な鍵:\n"
+
+#, c-format
 msgid "rounded to %u bits\n"
 msgstr "%uビットに切り上げます\n"
 
@@ -4478,7 +4494,7 @@ msgstr "以下に鍵があります: "
 
 #, c-format
 msgid "Note: Use '%s' to make use of this info\n"
-msgstr ""
+msgstr "注意: この情報を利用するには '%s' を使ってください\n"
 
 msgid "[uncertain]"
 msgstr "[不確定]"
@@ -4573,6 +4589,11 @@ msgstr "*警告*: ダイジェスト・アルゴリズム %s は廃止されて
 msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "注意: アルゴリズム %s を用いた署名は拒否されました\n"
 
+#, fuzzy, c-format
+#| msgid "Note: signatures using the %s algorithm are rejected\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "注意: アルゴリズム %s を用いた署名は拒否されました\n"
+
 #, c-format
 msgid "(reported error: %s)\n"
 msgstr "(報告されたエラー: %s)\n"
@@ -6621,17 +6642,6 @@ msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) カードに存在する鍵\n"
 
 #, c-format
-msgid "error reading the card: %s\n"
-msgstr "カードの読み込みエラー: %s\n"
-
-#, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "カードのシリアル番号: %s\n"
-
-msgid "Available keys:\n"
-msgstr "利用可能な鍵:\n"
-
-#, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr "%s鍵に可能な操作:\n"
 
@@ -8411,15 +8421,13 @@ msgstr "パスフレーズ入力"
 msgid "Component not suitable for launching"
 msgstr "コンポーネントが起動するために適切ではありません"
 
-#, fuzzy, c-format
-#| msgid "External verification of component %s failed"
+#, c-format
 msgid "Configuration file of component %s is broken\n"
-msgstr "コンポーネント%sの外部の検証が失敗しました"
+msgstr "コンポーネント%sのコンフィグレーション・ファイルが壊れています\n"
 
-#, fuzzy, c-format
-#| msgid "Note: Use the command \"%s\" to restart them.\n"
+#, c-format
 msgid "Note: Use the command \"%s%s\" to get details.\n"
-msgstr "注意: \"%s\"ã\82³ã\83\9eã\83³ã\83\89ã\82\92使ã\81£ã\81¦å\86\8dèµ·å\8b\95ã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84ã\80\82\n"
+msgstr "注意: \"%s%s\"ã\82³ã\83\9eã\83³ã\83\89ã\82\92使ã\81£ã\81¦è©³ç´°ã\82\92å¾\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84ã\80\82\n"
 
 #, c-format
 msgid "External verification of component %s failed"
@@ -8652,6 +8660,18 @@ msgstr ""
 "形式: gpg-check-pattern [オプション] パターンファイル\n"
 "パターンファイルに対して標準入力のパスフレーズを確認する\n"
 
+#~ msgid "male"
+#~ msgstr "男"
+
+#~ msgid "female"
+#~ msgstr "女"
+
+#~ msgid "unspecified"
+#~ msgstr "無指定"
+
+#~ msgid "Sex ((M)ale, (F)emale or space): "
+#~ msgstr "性別 ((M)男、(F)女、または空白): "
+
 #~ msgid "no keyserver known (use option --keyserver)\n"
 #~ msgstr "既知の鍵サーバがありません (オプション--keyserverを使いましょう)\n"
 
index c46d8a6..08c21a2 100644 (file)
--- a/po/nb.po
+++ b/po/nb.po
@@ -100,6 +100,7 @@ msgstr "feil. Prøv igjen"
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr "SETERROR %s (forsøk %d av %d)"
@@ -1268,14 +1269,11 @@ msgstr "Ditt valg? "
 msgid "[not set]"
 msgstr "[ikke valgt]"
 
-msgid "male"
-msgstr "mann"
-
-msgid "female"
-msgstr "dame"
+msgid "Mr."
+msgstr ""
 
-msgid "unspecified"
-msgstr "uspesifisert"
+msgid "Ms."
+msgstr ""
 
 msgid "not forced"
 msgstr "ikke tvunget"
@@ -1328,8 +1326,8 @@ msgstr "Feil: oppsettsstreng har ugyldig lengde.\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "Feil: oppsettsstreng inneholder ugyldige tegn.\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
-msgstr "Kjønn ((M)askulint, (F)eminint eller mellomrom): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
+msgstr ""
 
 msgid "Error: invalid response.\n"
 msgstr "Feil: ugyldig svar.\n"
@@ -1512,7 +1510,9 @@ msgstr "endre brukernavn"
 msgid "change the language preferences"
 msgstr "endre språkoppsett"
 
-msgid "change card holder's sex"
+#, fuzzy
+#| msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr "endre kortholders kjønn"
 
 msgid "change a CA fingerprint"
@@ -3842,14 +3842,14 @@ msgstr "Autentisere"
 # A og a for autentisering
 # Q og q for avslutte
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr "SsKkAaQq"
@@ -3929,6 +3929,11 @@ msgstr "  (%d) ECC (kun kryptering)\n"
 msgid "  (%d) Existing key\n"
 msgstr "  (%d) Nøkkel\n"
 
+#, fuzzy, c-format
+#| msgid "   (%d) Existing key from card\n"
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) Nøkkel fra kort\n"
+
 msgid "Enter the keygrip: "
 msgstr "Skriv inn nøkkelgrep: "
 
@@ -3939,6 +3944,17 @@ msgid "No key with this keygrip\n"
 msgstr "Ingen nøkkel med dette nøkkelgrepet\n"
 
 #, c-format
+msgid "error reading the card: %s\n"
+msgstr "feil under lesing av kort: %s\n"
+
+#, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "Kortets serienummer: %s\n"
+
+msgid "Available keys:\n"
+msgstr "Tilgjengelige nøkler:\n"
+
+#, c-format
 msgid "rounded to %u bits\n"
 msgstr "rundet av til %u bit\n"
 
@@ -4651,6 +4667,11 @@ msgstr "ADVARSEL: kontrollsum-algoritmen «%s» er utgått\n"
 msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "Merk: signaturer som bruker algoritmen %s blir avvist\n"
 
+#, fuzzy, c-format
+#| msgid "Note: signatures using the %s algorithm are rejected\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "Merk: signaturer som bruker algoritmen %s blir avvist\n"
+
 #, c-format
 msgid "(reported error: %s)\n"
 msgstr "(rapportert feil: %s)\n"
@@ -6757,17 +6778,6 @@ msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) Nøkkel fra kort\n"
 
 #, c-format
-msgid "error reading the card: %s\n"
-msgstr "feil under lesing av kort: %s\n"
-
-#, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "Kortets serienummer: %s\n"
-
-msgid "Available keys:\n"
-msgstr "Tilgjengelige nøkler:\n"
-
-#, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr "Mulige handlinger for %s-nøkler:\n"
 
@@ -8793,6 +8803,18 @@ msgstr ""
 "Syntaks: gpg-check-pattern [valg] mønsterfil\n"
 "Kontroller passordfrase oppgitt på standard innkanal mot valgt mønsterfil\n"
 
+#~ msgid "male"
+#~ msgstr "mann"
+
+#~ msgid "female"
+#~ msgstr "dame"
+
+#~ msgid "unspecified"
+#~ msgstr "uspesifisert"
+
+#~ msgid "Sex ((M)ale, (F)emale or space): "
+#~ msgstr "Kjønn ((M)askulint, (F)eminint eller mellomrom): "
+
 #~ msgid "no keyserver known (use option --keyserver)\n"
 #~ msgstr "ingen kjent nøkkeltjener (bruk valget «--keyserver»)\n"
 
index 043d3fa..8a1b194 100644 (file)
--- a/po/pl.po
+++ b/po/pl.po
@@ -94,6 +94,7 @@ msgstr "nie pasują - proszę spróbować jeszcze raz"
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr "SETERROR %s (próba %d z %d)"
@@ -1260,14 +1261,11 @@ msgstr "Twój wybór? "
 msgid "[not set]"
 msgstr "[nie ustawiono]"
 
-msgid "male"
-msgstr "mężczyzna"
-
-msgid "female"
-msgstr "kobieta"
+msgid "Mr."
+msgstr ""
 
-msgid "unspecified"
-msgstr "nie podano"
+msgid "Ms."
+msgstr ""
 
 msgid "not forced"
 msgstr "nie wymuszono"
@@ -1320,8 +1318,8 @@ msgstr "Błąd: niewłaściwa długość tekstu preferencji.\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "Błąd: niewłaściwe znaki w tekście preferencji.\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
-msgstr "Płeć (M - mężczyzna, F - kobieta lub spacja): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
+msgstr ""
 
 msgid "Error: invalid response.\n"
 msgstr "Błąd: niewłaściwa odpowiedź.\n"
@@ -1493,7 +1491,9 @@ msgstr "zmiana nazwy logowania"
 msgid "change the language preferences"
 msgstr "zmiana preferowanych języków"
 
-msgid "change card holder's sex"
+#, fuzzy
+#| msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr "zmiana płci posiadacza karty"
 
 msgid "change a CA fingerprint"
@@ -3859,14 +3859,14 @@ msgid "Authenticate"
 msgstr "Uwierzytelnianie"
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr "PpSsUuZz"
@@ -3946,6 +3946,11 @@ msgstr "   (%d) ECC (tylko do szyfrowania)\n"
 msgid "  (%d) Existing key\n"
 msgstr "   (%d) Istniejący klucz\n"
 
+#, fuzzy, c-format
+#| msgid "   (%d) Existing key from card\n"
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) Istniejący klucz z karty\n"
+
 msgid "Enter the keygrip: "
 msgstr "Uchwyt klucza: "
 
@@ -3956,6 +3961,17 @@ msgid "No key with this keygrip\n"
 msgstr "Brak klucza o tym uchwycie\n"
 
 #, c-format
+msgid "error reading the card: %s\n"
+msgstr "błąd odczytu karty: %s\n"
+
+#, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "Numer seryjny karty: %s\n"
+
+msgid "Available keys:\n"
+msgstr "Dostępne klucze:\n"
+
+#, c-format
 msgid "rounded to %u bits\n"
 msgstr "zaokrąglono do %u bitów\n"
 
@@ -4694,6 +4710,11 @@ msgstr "OSTRZEŻENIE: algorytm skrótu %s jest odradzany\n"
 msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "Uwaga: podpisy wykorzystujące algorytm %s są odrzucane\n"
 
+#, fuzzy, c-format
+#| msgid "Note: signatures using the %s algorithm are rejected\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "Uwaga: podpisy wykorzystujące algorytm %s są odrzucane\n"
+
 #, c-format
 msgid "(reported error: %s)\n"
 msgstr "(zgłoszony błąd: %s)\n"
@@ -6871,17 +6892,6 @@ msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) Istniejący klucz z karty\n"
 
 #, c-format
-msgid "error reading the card: %s\n"
-msgstr "błąd odczytu karty: %s\n"
-
-#, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "Numer seryjny karty: %s\n"
-
-msgid "Available keys:\n"
-msgstr "Dostępne klucze:\n"
-
-#, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr "Możliwe akcje dla klucza %s:\n"
 
@@ -8925,3 +8935,15 @@ msgid ""
 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 "male"
+#~ msgstr "mężczyzna"
+
+#~ msgid "female"
+#~ msgstr "kobieta"
+
+#~ msgid "unspecified"
+#~ msgstr "nie podano"
+
+#~ msgid "Sex ((M)ale, (F)emale or space): "
+#~ msgstr "Płeć (M - mężczyzna, F - kobieta lub spacja): "
index 68f9403..6a1548c 100644 (file)
--- a/po/pt.po
+++ b/po/pt.po
@@ -95,6 +95,7 @@ msgstr ""
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -1335,17 +1336,11 @@ msgstr "Opção? "
 msgid "[not set]"
 msgstr ""
 
-#, fuzzy
-msgid "male"
-msgstr "enable"
-
-#, fuzzy
-msgid "female"
-msgstr "enable"
+msgid "Mr."
+msgstr ""
 
-#, fuzzy
-msgid "unspecified"
-msgstr "Nenhum motivo especificado"
+msgid "Ms."
+msgstr ""
 
 #, fuzzy
 msgid "not forced"
@@ -1404,7 +1399,7 @@ msgstr "caracter inválido na cadeia de caractéres da preferência\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "caracter inválido na cadeia de caractéres da preferência\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
 msgstr ""
 
 #, fuzzy
@@ -1587,7 +1582,7 @@ msgstr "muda a data de validade"
 msgid "change the language preferences"
 msgstr "muda os valores de confiança"
 
-msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr ""
 
 #, fuzzy
@@ -4071,14 +4066,14 @@ msgid "Authenticate"
 msgstr ""
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr ""
@@ -4160,6 +4155,10 @@ msgstr "   (%d) RSA (apenas cifragem)\n"
 msgid "  (%d) Existing key\n"
 msgstr "   (%d) RSA (apenas cifragem)\n"
 
+#, fuzzy, c-format
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) RSA (apenas cifragem)\n"
+
 #, fuzzy
 msgid "Enter the keygrip: "
 msgstr "Notação de assinatura: "
@@ -4172,6 +4171,18 @@ msgid "No key with this keygrip\n"
 msgstr "Nenhum ID de utilizador com índice %d\n"
 
 #, fuzzy, c-format
+msgid "error reading the card: %s\n"
+msgstr "%s: erro ao ler registo livre: %s\n"
+
+#, fuzzy, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "erro na criação da frase secreta: %s\n"
+
+#, fuzzy
+msgid "Available keys:\n"
+msgstr "desactiva uma chave"
+
+#, fuzzy, c-format
 #| msgid "rounded up to %u bits\n"
 msgid "rounded to %u bits\n"
 msgstr "arredondado para %u bits\n"
@@ -4918,6 +4929,10 @@ msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "assinatura %s de: \"%s\"\n"
 
 #, fuzzy, c-format
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "assinatura %s de: \"%s\"\n"
+
+#, fuzzy, c-format
 msgid "(reported error: %s)\n"
 msgstr "armadura: %s\n"
 
@@ -7049,18 +7064,6 @@ msgstr "   (%d) RSA (apenas cifragem)\n"
 msgid "   (%d) Existing key from card\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "error reading the card: %s\n"
-msgstr "%s: erro ao ler registo livre: %s\n"
-
-#, fuzzy, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "erro na criação da frase secreta: %s\n"
-
-#, fuzzy
-msgid "Available keys:\n"
-msgstr "desactiva uma chave"
-
 #, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr ""
@@ -9155,6 +9158,18 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "male"
+#~ msgstr "enable"
+
+#, fuzzy
+#~ msgid "female"
+#~ msgstr "enable"
+
+#, fuzzy
+#~ msgid "unspecified"
+#~ msgstr "Nenhum motivo especificado"
+
+#, fuzzy
 #~ msgid "error creating 'ultimately_trusted_keys' TOFU table: %s\n"
 #~ msgstr "erro na criação da frase secreta: %s\n"
 
index 8c292a8..4857e71 100644 (file)
--- a/po/ro.po
+++ b/po/ro.po
@@ -99,6 +99,7 @@ msgstr ""
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -1357,14 +1358,11 @@ msgstr "Selecţia d-voastră? "
 msgid "[not set]"
 msgstr "[nesetat(ă)]"
 
-msgid "male"
-msgstr "masculin"
-
-msgid "female"
-msgstr "feminin"
+msgid "Mr."
+msgstr ""
 
-msgid "unspecified"
-msgstr "nespecificat(ă)"
+msgid "Ms."
+msgstr ""
 
 msgid "not forced"
 msgstr "neforţat(ă)"
@@ -1418,8 +1416,8 @@ msgstr "Eroare: lungime invalidă pentru şir preferinţe.\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "Eroare: caractere invalide în şir preferinţe.\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
-msgstr "Sex ((M)asculin, (F)eminin sau spaţiu): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
+msgstr ""
 
 msgid "Error: invalid response.\n"
 msgstr "Eroare: răspuns invalid.\n"
@@ -1602,7 +1600,9 @@ msgstr "schimbă numele de login"
 msgid "change the language preferences"
 msgstr "schimbă preferinţele de limbă"
 
-msgid "change card holder's sex"
+#, fuzzy
+#| msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr "schimbă sexul purtătorului cardului"
 
 msgid "change a CA fingerprint"
@@ -4110,14 +4110,14 @@ msgid "Authenticate"
 msgstr "Autentifică"
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr "SsCcAaTt"
@@ -4200,6 +4200,10 @@ msgstr "   (%d) RSA (numai cifrare)\n"
 msgid "  (%d) Existing key\n"
 msgstr "   (2) Cheie de cifrare\n"
 
+#, fuzzy, c-format
+msgid "  (%d) Existing key from card\n"
+msgstr "   (2) Cheie de cifrare\n"
+
 #, fuzzy
 msgid "Enter the keygrip: "
 msgstr "Notare semnătură: "
@@ -4212,6 +4216,18 @@ msgid "No key with this keygrip\n"
 msgstr "Nici o subcheie cu indicele %d\n"
 
 #, fuzzy, c-format
+msgid "error reading the card: %s\n"
+msgstr "%s: eroare citire înregistrare liberă: %s\n"
+
+#, fuzzy, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "eroare la obţinerea numărului serial: %s\n"
+
+#, fuzzy
+msgid "Available keys:\n"
+msgstr "deactivează cheia"
+
+#, fuzzy, c-format
 #| msgid "rounded up to %u bits\n"
 msgid "rounded to %u bits\n"
 msgstr "rotunjită prin adaos la %u biţi\n"
@@ -4955,6 +4971,11 @@ msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "semnătură %s, algoritm rezumat %s\n"
 
 #, fuzzy, c-format
+#| msgid "%s signature, digest algorithm %s\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "semnătură %s, algoritm rezumat %s\n"
+
+#, fuzzy, c-format
 #| msgid "read error in `%s': %s\n"
 msgid "(reported error: %s)\n"
 msgstr "eroare citire în `%s': %s\n"
@@ -7137,18 +7158,6 @@ msgid "   (%d) Existing key from card\n"
 msgstr ""
 
 #, fuzzy, c-format
-msgid "error reading the card: %s\n"
-msgstr "%s: eroare citire înregistrare liberă: %s\n"
-
-#, fuzzy, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "eroare la obţinerea numărului serial: %s\n"
-
-#, fuzzy
-msgid "Available keys:\n"
-msgstr "deactivează cheia"
-
-#, fuzzy, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr "Acţiuni posibile pentru o cheie %s: "
 
@@ -9270,6 +9279,18 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
+#~ msgid "male"
+#~ msgstr "masculin"
+
+#~ msgid "female"
+#~ msgstr "feminin"
+
+#~ msgid "unspecified"
+#~ msgstr "nespecificat(ă)"
+
+#~ msgid "Sex ((M)ale, (F)emale or space): "
+#~ msgstr "Sex ((M)asculin, (F)eminin sau spaţiu): "
+
 #~ msgid "no keyserver known (use option --keyserver)\n"
 #~ msgstr "nici un server de chei cunoscut (folosiţi opţiunea --keyserver)\n"
 
index 5607362..27f82fa 100644 (file)
--- a/po/ru.po
+++ b/po/ru.po
@@ -97,6 +97,7 @@ msgstr "не подходит - попробуйте еще раз"
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr "SETERROR %s (попытка %d из %d)"
@@ -1270,14 +1271,11 @@ msgstr "Ваш выбор? "
 msgid "[not set]"
 msgstr "[не установлено]"
 
-msgid "male"
-msgstr "мужской"
-
-msgid "female"
-msgstr "женский"
+msgid "Mr."
+msgstr ""
 
-msgid "unspecified"
-msgstr "не указан"
+msgid "Ms."
+msgstr ""
 
 msgid "not forced"
 msgstr "не требуется"
@@ -1330,8 +1328,8 @@ msgstr "Ошибка: недопустимая длина строки пред
 msgid "Error: invalid characters in preference string.\n"
 msgstr "Ошибка: недопустимые символы в строке предпочтений.\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
-msgstr "Пол ((M) мужской, (F) женский или пробел): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
+msgstr ""
 
 msgid "Error: invalid response.\n"
 msgstr "Ошибка: недопустимый ответ.\n"
@@ -1503,7 +1501,9 @@ msgstr "изменить имя учетной записи"
 msgid "change the language preferences"
 msgstr "изменить языковые предпочтения"
 
-msgid "change card holder's sex"
+#, fuzzy
+#| msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr "изменить пол держателя карты"
 
 msgid "change a CA fingerprint"
@@ -3856,14 +3856,14 @@ msgid "Authenticate"
 msgstr "Удостоверить личность"
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr "11223300"
@@ -3943,6 +3943,11 @@ msgstr "  (%d) ECC (только для шифрования)\n"
 msgid "  (%d) Existing key\n"
 msgstr "  (%d) Имеющийся ключ\n"
 
+#, fuzzy, c-format
+#| msgid "   (%d) Existing key from card\n"
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) Имеющийся на карте ключ\n"
+
 msgid "Enter the keygrip: "
 msgstr "Введите код ключа:"
 
@@ -3953,6 +3958,17 @@ msgid "No key with this keygrip\n"
 msgstr "Нет ключа с таким кодом\n"
 
 #, c-format
+msgid "error reading the card: %s\n"
+msgstr "ошибка чтения карты: %s\n"
+
+#, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "Серийный номер карты: %s\n"
+
+msgid "Available keys:\n"
+msgstr "Доступные ключи:\n"
+
+#, c-format
 msgid "rounded to %u bits\n"
 msgstr "округлен до %u бит\n"
 
@@ -4679,6 +4695,11 @@ msgstr "Внимание: хеш-функция %s не рекомендуетс
 msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "Замечание: подписи с хеш-функцией %s игнорируются\n"
 
+#, fuzzy, c-format
+#| msgid "Note: signatures using the %s algorithm are rejected\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "Замечание: подписи с хеш-функцией %s игнорируются\n"
+
 #, c-format
 msgid "(reported error: %s)\n"
 msgstr "(сообщенная ошибка: %s)\n"
@@ -6833,17 +6854,6 @@ msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) Имеющийся на карте ключ\n"
 
 #, c-format
-msgid "error reading the card: %s\n"
-msgstr "ошибка чтения карты: %s\n"
-
-#, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "Серийный номер карты: %s\n"
-
-msgid "Available keys:\n"
-msgstr "Доступные ключи:\n"
-
-#, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr "Возможные действия для ключа %s:\n"
 
@@ -8905,6 +8915,18 @@ msgstr ""
 "Синтаксис: gpg-check-pattern [параметры] файл_образцов\n"
 "Проверить фразу-пароль, поступающую из stdin, по файлу образцов\n"
 
+#~ msgid "male"
+#~ msgstr "мужской"
+
+#~ msgid "female"
+#~ msgstr "женский"
+
+#~ msgid "unspecified"
+#~ msgstr "не указан"
+
+#~ msgid "Sex ((M)ale, (F)emale or space): "
+#~ msgstr "Пол ((M) мужской, (F) женский или пробел): "
+
 #~ msgid "no keyserver known (use option --keyserver)\n"
 #~ msgstr "не заданы серверы ключей (используйте --keyserver)\n"
 
index d8a6bb4..4fedcdc 100644 (file)
--- a/po/sk.po
+++ b/po/sk.po
@@ -95,6 +95,7 @@ msgstr ""
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -1336,17 +1337,11 @@ msgstr "Váš výber? "
 msgid "[not set]"
 msgstr ""
 
-#, fuzzy
-msgid "male"
-msgstr "enable"
-
-#, fuzzy
-msgid "female"
-msgstr "enable"
+msgid "Mr."
+msgstr ""
 
-#, fuzzy
-msgid "unspecified"
-msgstr "Dôvod nebol špecifikovaný"
+msgid "Ms."
+msgstr ""
 
 #, fuzzy
 msgid "not forced"
@@ -1405,7 +1400,7 @@ msgstr "neplatný znak v reťazci s predvoľbami\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "neplatný znak v reťazci s predvoľbami\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
 msgstr ""
 
 #, fuzzy
@@ -1588,7 +1583,7 @@ msgstr "zmeniť dobu platnosti"
 msgid "change the language preferences"
 msgstr "zmeniť dôveryhodnosť vlastníka kľúča"
 
-msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr ""
 
 #, fuzzy
@@ -4085,14 +4080,14 @@ msgid "Authenticate"
 msgstr ""
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr ""
@@ -4174,6 +4169,10 @@ msgstr "   (%d) RSA (len na šifrovanie)\n"
 msgid "  (%d) Existing key\n"
 msgstr "   (%d) RSA (len na šifrovanie)\n"
 
+#, fuzzy, c-format
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) RSA (len na šifrovanie)\n"
+
 #, fuzzy
 msgid "Enter the keygrip: "
 msgstr "Podpisová notácia: "
@@ -4186,6 +4185,18 @@ msgid "No key with this keygrip\n"
 msgstr "Neexistuje identifikátor užívateľa s indexom %d\n"
 
 #, fuzzy, c-format
+msgid "error reading the card: %s\n"
+msgstr "%s: chyba pri čítaní voľného záznamu: %s\n"
+
+#, fuzzy, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "chyba pri vytváraní hesla: %s\n"
+
+#, fuzzy
+msgid "Available keys:\n"
+msgstr "nastaviť kľúč ako neplatný (disable)"
+
+#, fuzzy, c-format
 #| msgid "rounded up to %u bits\n"
 msgid "rounded to %u bits\n"
 msgstr "zaokrúhlené na %u bitov\n"
@@ -4931,6 +4942,11 @@ msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "%s podpis, hashovací algoritmus %s\n"
 
 #, fuzzy, c-format
+#| msgid "%s signature, digest algorithm %s\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "%s podpis, hashovací algoritmus %s\n"
+
+#, fuzzy, c-format
 msgid "(reported error: %s)\n"
 msgstr "chyba pri čítaní: %s\n"
 
@@ -7077,18 +7093,6 @@ msgstr "   (%d) RSA (len na šifrovanie)\n"
 msgid "   (%d) Existing key from card\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "error reading the card: %s\n"
-msgstr "%s: chyba pri čítaní voľného záznamu: %s\n"
-
-#, fuzzy, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "chyba pri vytváraní hesla: %s\n"
-
-#, fuzzy
-msgid "Available keys:\n"
-msgstr "nastaviť kľúč ako neplatný (disable)"
-
 #, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr ""
@@ -9184,6 +9188,18 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "male"
+#~ msgstr "enable"
+
+#, fuzzy
+#~ msgid "female"
+#~ msgstr "enable"
+
+#, fuzzy
+#~ msgid "unspecified"
+#~ msgstr "Dôvod nebol špecifikovaný"
+
+#, fuzzy
 #~ msgid "error creating 'ultimately_trusted_keys' TOFU table: %s\n"
 #~ msgstr "chyba pri vytváraní hesla: %s\n"
 
index f8e4d8f..9b9caa0 100644 (file)
--- a/po/sv.po
+++ b/po/sv.po
@@ -124,6 +124,7 @@ msgstr "stämmer inte överens - försök igen"
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr "SETERROR %s (försök %d av %d)"
@@ -1415,14 +1416,11 @@ msgstr "Vad väljer du? "
 msgid "[not set]"
 msgstr "[inte inställt]"
 
-msgid "male"
-msgstr "man"
-
-msgid "female"
-msgstr "kvinna"
+msgid "Mr."
+msgstr ""
 
-msgid "unspecified"
-msgstr "ej angiven"
+msgid "Ms."
+msgstr ""
 
 msgid "not forced"
 msgstr "inte tvingad"
@@ -1477,8 +1475,8 @@ msgstr "Fel: ogiltig längd på inställningssträngen\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "Fel: ogiltiga tecken i inställningssträngen.\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
-msgstr "Kön ((M)an, Kvinna(F) eller blanksteg): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
+msgstr ""
 
 msgid "Error: invalid response.\n"
 msgstr "Fel: ogiltigt svar.\n"
@@ -1677,7 +1675,9 @@ msgstr "ändra inloggningsnamnet"
 msgid "change the language preferences"
 msgstr "ändra språkinställningarna"
 
-msgid "change card holder's sex"
+#, fuzzy
+#| msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr "ändra kortinnehavarens kön"
 
 msgid "change a CA fingerprint"
@@ -4213,14 +4213,14 @@ msgstr "Autentisera"
 # A = Authentisera
 # Q = Avsluta
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr "SsKkAaQq"
@@ -4305,6 +4305,11 @@ msgstr "   (%d) RSA (endast kryptering)\n"
 msgid "  (%d) Existing key\n"
 msgstr "   (%d) Befintlig nyckel\n"
 
+#, fuzzy, c-format
+#| msgid "   (%d) Existing key from card\n"
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) Befintlig nyckel från kort\n"
+
 msgid "Enter the keygrip: "
 msgstr "Ange nyckelhashen: "
 
@@ -4314,6 +4319,17 @@ msgstr "Inte en giltig nyckelhash (förväntade 40 hexadecimala siffror)\n"
 msgid "No key with this keygrip\n"
 msgstr "Ingen nyckel med denna nyckelhash\n"
 
+#, c-format
+msgid "error reading the card: %s\n"
+msgstr "fel vid läsning av kortet: %s\n"
+
+#, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "Serienummer för kortet: %s\n"
+
+msgid "Available keys:\n"
+msgstr "Tillgängliga nycklar:\n"
+
 #, fuzzy, c-format
 #| msgid "rounded up to %u bits\n"
 msgid "rounded to %u bits\n"
@@ -5076,6 +5092,11 @@ msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "%s signatur, sammandragsalgoritm %s\n"
 
 #, fuzzy, c-format
+#| msgid "%s signature, digest algorithm %s\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "%s signatur, sammandragsalgoritm %s\n"
+
+#, fuzzy, c-format
 #| msgid "read error in `%s': %s\n"
 msgid "(reported error: %s)\n"
 msgstr "läsfel i \"%s\":  %s\n"
@@ -7339,17 +7360,6 @@ msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) Befintlig nyckel från kort\n"
 
 #, c-format
-msgid "error reading the card: %s\n"
-msgstr "fel vid läsning av kortet: %s\n"
-
-#, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "Serienummer för kortet: %s\n"
-
-msgid "Available keys:\n"
-msgstr "Tillgängliga nycklar:\n"
-
-#, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr "Möjliga åtgärder för en %s-nyckel:\n"
 
@@ -9647,6 +9657,18 @@ msgstr ""
 "Syntax: gpg-check-pattern [flaggor] mönsterfil\n"
 "Kontrollera en lösenfras angiven på standard in mot mönsterfilen\n"
 
+#~ msgid "male"
+#~ msgstr "man"
+
+#~ msgid "female"
+#~ msgstr "kvinna"
+
+#~ msgid "unspecified"
+#~ msgstr "ej angiven"
+
+#~ msgid "Sex ((M)ale, (F)emale or space): "
+#~ msgstr "Kön ((M)an, Kvinna(F) eller blanksteg): "
+
 #~ msgid "no keyserver known (use option --keyserver)\n"
 #~ msgstr "ingen nyckelserver är känd (använd flaggan --keyserver)\n"
 
index 971b047..7891344 100644 (file)
--- a/po/tr.po
+++ b/po/tr.po
@@ -98,6 +98,7 @@ msgstr "aynı değiller - tekrar deneyin"
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr "SETERROR %s (%d/%d dene)"
@@ -1382,14 +1383,11 @@ msgstr "Seçiminiz? "
 msgid "[not set]"
 msgstr "[belirtilmedi]"
 
-msgid "male"
-msgstr "erkek"
-
-msgid "female"
-msgstr "dişi"
+msgid "Mr."
+msgstr ""
 
-msgid "unspecified"
-msgstr "belirtilmemiş"
+msgid "Ms."
+msgstr ""
 
 msgid "not forced"
 msgstr "zorlanmadı"
@@ -1443,8 +1441,8 @@ msgstr "Hata: tercih dizgesinin uzunluğu geçersiz.\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "Hata: tercih dizgesindeki karakterler geçersiz.\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
-msgstr "Cinsiyet ((E)rkek, (D)işi veya boşluk): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
+msgstr ""
 
 msgid "Error: invalid response.\n"
 msgstr "Hata: yanıt geçersiz.\n"
@@ -1629,7 +1627,9 @@ msgstr "oturum açma ismini değiştirir"
 msgid "change the language preferences"
 msgstr "dil tercihlerini değiştirir"
 
-msgid "change card holder's sex"
+#, fuzzy
+#| msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr "kart sahibinin cinsiyetini değiştirir"
 
 msgid "change a CA fingerprint"
@@ -4163,14 +4163,14 @@ msgid "Authenticate"
 msgstr "Kimlik kanıtla"
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr "OoŞşKkçÇ"
@@ -4254,6 +4254,11 @@ msgstr "   (%d) RSA (sadece şifrelemek için)\n"
 msgid "  (%d) Existing key\n"
 msgstr "   (%d) Mevcut anahtar\n"
 
+#, fuzzy, c-format
+#| msgid "   (%d) Existing key from card\n"
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) Karttaki mevcut anahtar\n"
+
 #, fuzzy
 msgid "Enter the keygrip: "
 msgstr "Simgelemi giriniz: "
@@ -4266,6 +4271,18 @@ msgid "No key with this keygrip\n"
 msgstr "%d indisli bir yardımcı anahtar yok\n"
 
 #, fuzzy, c-format
+msgid "error reading the card: %s\n"
+msgstr "%s: serbest kaydı okuma hatası: %s\n"
+
+#, fuzzy, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "kartın seri numarası alınırken hata: %s\n"
+
+#, fuzzy
+msgid "Available keys:\n"
+msgstr "anahtarı iptal eder"
+
+#, fuzzy, c-format
 #| msgid "rounded up to %u bits\n"
 msgid "rounded to %u bits\n"
 msgstr "%u bite yuvarlandı\n"
@@ -5016,6 +5033,11 @@ msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "%s imzası, %s özet algoritması\n"
 
 #, fuzzy, c-format
+#| msgid "%s signature, digest algorithm %s\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "%s imzası, %s özet algoritması\n"
+
+#, fuzzy, c-format
 #| msgid "read error in `%s': %s\n"
 msgid "(reported error: %s)\n"
 msgstr "`%s' için okuma hatası: %s\n"
@@ -7243,18 +7265,6 @@ msgstr "   (%d) Mevcut anahtar\n"
 msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) Karttaki mevcut anahtar\n"
 
-#, fuzzy, c-format
-msgid "error reading the card: %s\n"
-msgstr "%s: serbest kaydı okuma hatası: %s\n"
-
-#, fuzzy, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "kartın seri numarası alınırken hata: %s\n"
-
-#, fuzzy
-msgid "Available keys:\n"
-msgstr "anahtarı iptal eder"
-
 #, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr "bir %s anahtarı için olası eylemler:\n"
@@ -9549,6 +9559,18 @@ msgstr ""
 "Standart girdiden verilen anahtar parolasını örüntü dosyasıyla "
 "karşılaştırır\n"
 
+#~ msgid "male"
+#~ msgstr "erkek"
+
+#~ msgid "female"
+#~ msgstr "dişi"
+
+#~ msgid "unspecified"
+#~ msgstr "belirtilmemiş"
+
+#~ msgid "Sex ((M)ale, (F)emale or space): "
+#~ msgstr "Cinsiyet ((E)rkek, (D)işi veya boşluk): "
+
 #~ msgid "no keyserver known (use option --keyserver)\n"
 #~ msgstr ""
 #~ "bilinen bir anahtar sunucusu yok (--keyserver seçeneğini kullanın)\n"
index edc32ce..27f2fd7 100644 (file)
--- a/po/uk.po
+++ b/po/uk.po
@@ -97,6 +97,7 @@ msgstr "паролі не збігаються, повторіть спробу"
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr "SETERROR %s (спроба %d з %d)"
@@ -1279,14 +1280,11 @@ msgstr "Ваш вибір? "
 msgid "[not set]"
 msgstr "[не встановлено]"
 
-msgid "male"
-msgstr "чоловіча"
-
-msgid "female"
-msgstr "жіноча"
+msgid "Mr."
+msgstr ""
 
-msgid "unspecified"
-msgstr "не вказано"
+msgid "Ms."
+msgstr ""
 
 msgid "not forced"
 msgstr "не увімкнено"
@@ -1340,8 +1338,8 @@ msgstr "Помилка: некоректна довжина рядка осно
 msgid "Error: invalid characters in preference string.\n"
 msgstr "Помилка: некоректні символи у рядку основної мови.\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
-msgstr "Стать (чоловіча (M), жіноча (F) або пробіл): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
+msgstr ""
 
 msgid "Error: invalid response.\n"
 msgstr "Помилка: некоректна відповідь.\n"
@@ -1529,7 +1527,9 @@ msgstr "змінити ім’я користувача"
 msgid "change the language preferences"
 msgstr "змінити основну мову"
 
-msgid "change card holder's sex"
+#, fuzzy
+#| msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr "змінити поле статі власника картки"
 
 msgid "change a CA fingerprint"
@@ -3931,14 +3931,14 @@ msgid "Authenticate"
 msgstr "Пройти розпізнавання"
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr "SsEeAaQq"
@@ -4019,6 +4019,11 @@ msgstr "  (%d) ECC (лише шифрування)\n"
 msgid "  (%d) Existing key\n"
 msgstr "   (%d) Вже записаний ключ\n"
 
+#, fuzzy, c-format
+#| msgid "   (%d) Existing key from card\n"
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) Вже записаний ключ з картки\n"
+
 msgid "Enter the keygrip: "
 msgstr "Вкажіть keygrip: "
 
@@ -4029,6 +4034,17 @@ msgid "No key with this keygrip\n"
 msgstr "Немає ключів з таким значенням keygrip\n"
 
 #, c-format
+msgid "error reading the card: %s\n"
+msgstr "помилка читання картки: %s\n"
+
+#, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "Серійний номер картки: %s\n"
+
+msgid "Available keys:\n"
+msgstr "Доступні ключі:\n"
+
+#, c-format
 msgid "rounded to %u bits\n"
 msgstr "округлено до %u бітів\n"
 
@@ -4766,6 +4782,11 @@ msgstr "УВАГА: алгоритм обчислення контрольних
 msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "Зауваження: підписи за допомогою алгоритму %s відкинуто\n"
 
+#, fuzzy, c-format
+#| msgid "Note: signatures using the %s algorithm are rejected\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "Зауваження: підписи за допомогою алгоритму %s відкинуто\n"
+
 #, c-format
 msgid "(reported error: %s)\n"
 msgstr "(повідомлена помилка: %s)\n"
@@ -6974,17 +6995,6 @@ msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) Вже записаний ключ з картки\n"
 
 #, c-format
-msgid "error reading the card: %s\n"
-msgstr "помилка читання картки: %s\n"
-
-#, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "Серійний номер картки: %s\n"
-
-msgid "Available keys:\n"
-msgstr "Доступні ключі:\n"
-
-#, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr "Можливі дії для ключа %s:\n"
 
@@ -9034,6 +9044,18 @@ msgstr ""
 "Синтаксис: gpg-check-pattern [параметри] файл_шаблонів\n"
 "Перевірити пароль, вказаний у stdin, за допомогою файла_шаблонів\n"
 
+#~ msgid "male"
+#~ msgstr "чоловіча"
+
+#~ msgid "female"
+#~ msgstr "жіноча"
+
+#~ msgid "unspecified"
+#~ msgstr "не вказано"
+
+#~ msgid "Sex ((M)ale, (F)emale or space): "
+#~ msgstr "Стать (чоловіча (M), жіноча (F) або пробіл): "
+
 #~ msgid "no keyserver known (use option --keyserver)\n"
 #~ msgstr ""
 #~ "не вказано жодного сервера ключів (скористайтеся параметром --keyserver)\n"
index a37ccab..58e36a0 100644 (file)
@@ -92,6 +92,7 @@ msgstr "不匹配 - 请重试"
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
 msgstr ""
@@ -1248,16 +1249,13 @@ msgstr "您的选择是? "
 msgid "[not set]"
 msgstr "[未设定]"
 
-msgid "male"
-msgstr ""
-
-msgid "female"
-msgstr ""
+msgid "Mr."
+msgstr "先生"
 
 #, fuzzy
-#| msgid "No reason specified"
-msgid "unspecified"
-msgstr "未指定原因"
+#| msgid "Mrs."
+msgid "Ms."
+msgstr "女士"
 
 msgid "not forced"
 msgstr "非强制"
@@ -1310,8 +1308,10 @@ msgstr "错误:偏好字符串长度无效。\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "错误:偏好字符串中存在无效字符。\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
-msgstr ""
+#, fuzzy
+#| msgid "Salutation (M = Mr., F = Mrs., or space): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
+msgstr "称呼(M = 先生,F = 女士,或者留空): "
 
 msgid "Error: invalid response.\n"
 msgstr "错误:无效的响应。\n"
@@ -1490,10 +1490,8 @@ msgstr "更改登录名"
 msgid "change the language preferences"
 msgstr "更改语言偏好"
 
-#, fuzzy
-#| msgid "change card holder's name"
-msgid "change card holder's sex"
-msgstr "更改卡持有人的姓名"
+msgid "change card holder's salutation"
+msgstr "变更卡片持有人的称呼"
 
 msgid "change a CA fingerprint"
 msgstr "更改一个 CA 指纹"
@@ -3759,14 +3757,14 @@ msgid "Authenticate"
 msgstr "身份验证(Authenticate)"
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr "SsEeAaQq"
@@ -3846,6 +3844,11 @@ msgstr "  (%d) ECC(仅用于加密)\n"
 msgid "  (%d) Existing key\n"
 msgstr "  (%d) 现存的密钥\n"
 
+#, fuzzy, c-format
+#| msgid "   (%d) Existing key from card\n"
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) 卡片上现存的密钥\n"
+
 msgid "Enter the keygrip: "
 msgstr "输入 keygrip: "
 
@@ -3856,6 +3859,17 @@ msgid "No key with this keygrip\n"
 msgstr "没有此 keygrip 关联的密钥\n"
 
 #, c-format
+msgid "error reading the card: %s\n"
+msgstr "读取卡片时出现错误:%s\n"
+
+#, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "卡片的序列号:%s\n"
+
+msgid "Available keys:\n"
+msgstr "可用的密钥:\n"
+
+#, c-format
 msgid "rounded to %u bits\n"
 msgstr "舍入到 %u 位\n"
 
@@ -4551,6 +4565,11 @@ msgstr "警告:散列算法 %s 已被弃用\n"
 msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "注意:使用 %s 算法的签名已被拒绝\n"
 
+#, fuzzy, c-format
+#| msgid "Note: signatures using the %s algorithm are rejected\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "注意:使用 %s 算法的签名已被拒绝\n"
+
 #, c-format
 msgid "(reported error: %s)\n"
 msgstr "(已报告错误:%s)\n"
@@ -6570,17 +6589,6 @@ msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) 卡片上现存的密钥\n"
 
 #, c-format
-msgid "error reading the card: %s\n"
-msgstr "读取卡片时出现错误:%s\n"
-
-#, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "卡片的序列号:%s\n"
-
-msgid "Available keys:\n"
-msgstr "可用的密钥:\n"
-
-#, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr "%s 密钥可能的操作:\n"
 
@@ -8597,6 +8605,16 @@ msgstr ""
 "语法:gpg-check-pattern [选项] patternfile\n"
 "按照 patternfile 检查一个由标准输入(stdin)给定的密码\n"
 
+#, fuzzy
+#~| msgid "No reason specified"
+#~ msgid "unspecified"
+#~ msgstr "未指定原因"
+
+#, fuzzy
+#~| msgid "change card holder's name"
+#~ msgid "change card holder's sex"
+#~ msgstr "更改卡持有人的姓名"
+
 #~ msgid "no keyserver known (use option --keyserver)\n"
 #~ msgstr "无已知的公钥服务器(使用 --keyserver 选项)\n"
 
@@ -8635,21 +8653,9 @@ msgstr ""
 #~ msgid "connection to the dirmngr established\n"
 #~ msgstr "与 dirmngr 的连接已建立\n"
 
-#~ msgid "Mr."
-#~ msgstr "先生"
-
-#~ msgid "Mrs."
-#~ msgstr "女士"
-
-#~ msgid "Salutation (M = Mr., F = Mrs., or space): "
-#~ msgstr "称呼(M = 先生,F = 女士,或者留空): "
-
 #~ msgid "error for setup UIF: %s\n"
 #~ msgstr "设置 KDF 时出现错误: %s\n"
 
-#~ msgid "change card holder's salutation"
-#~ msgstr "变更卡片持有人的称呼"
-
 #~ msgid "change the User Interaction Flag"
 #~ msgstr "变更用户交互选项"
 
index bba5bce..5120ee3 100644 (file)
@@ -9,7 +9,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: GNU gnupg 2.1.0\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2017-11-02 17:42+0100\n"
+"PO-Revision-Date: 2019-11-04 09:49+0100\n"
 "Last-Translator: Jedi Lin <Jedi@Jedi.org>\n"
 "Language-Team: Chinese (traditional) <zh-l10n@linux.org.tw>\n"
 "Language: zh_TW\n"
@@ -105,9 +105,10 @@ msgstr "前後不一致 - 請再試一次"
 #. TRANSLATORS: The string is appended to an error message in
 #. the pinentry.  The %s is the actual error message, the
 #. two %d give the current and maximum number of tries.
+#. Do not translate the "SETERROR" keyword.
 #, c-format
 msgid "SETERROR %s (try %d of %d)"
-msgstr "設定錯誤: %s (第 %d 次嘗試, 最多 %d 次)"
+msgstr "SETERROR %s (第 %d 次嘗試, 最多 %d 次)"
 
 msgid "Repeat:"
 msgstr "重複:"
@@ -1277,14 +1278,11 @@ msgstr "你要選哪一個? "
 msgid "[not set]"
 msgstr "[未設定]"
 
-msgid "male"
-msgstr "男性"
-
-msgid "female"
-msgstr "女性"
+msgid "Mr."
+msgstr ""
 
-msgid "unspecified"
-msgstr "未特定"
+msgid "Ms."
+msgstr ""
 
 msgid "not forced"
 msgstr "不強迫使用"
@@ -1337,8 +1335,8 @@ msgstr "錯誤: 無效的偏好設定字串長度\n"
 msgid "Error: invalid characters in preference string.\n"
 msgstr "錯誤: 偏好設定字串中含有無效的字符\n"
 
-msgid "Sex ((M)ale, (F)emale or space): "
-msgstr "性別 ((M)男性, (F)女性或留空): "
+msgid "Salutation (M = Mr., F = Ms., or space): "
+msgstr ""
 
 msgid "Error: invalid response.\n"
 msgstr "錯誤: 無效的回應.\n"
@@ -1525,7 +1523,9 @@ msgstr "變更登入名稱"
 msgid "change the language preferences"
 msgstr "變更介面語言偏好設定"
 
-msgid "change card holder's sex"
+#, fuzzy
+#| msgid "change card holder's sex"
+msgid "change card holder's salutation"
 msgstr "變更卡片持有者的性別"
 
 msgid "change a CA fingerprint"
@@ -3875,14 +3875,14 @@ msgid "Authenticate"
 msgstr "鑑定"
 
 #. TRANSLATORS: Please use only plain ASCII characters for the
-#. translation.  If this is not possible use single digits.  The
-#. string needs to 8 bytes long. Here is a description of the
-#. functions:
-#.
-#. s = Toggle signing capability
-#. e = Toggle encryption capability
-#. a = Toggle authentication capability
-#. q = Finish
+#. translation.  If this is not possible use single digits.  The
+#. string needs to 8 bytes long. Here is a description of the
+#. functions:
+#. *
+#. *   s = Toggle signing capability
+#. *   e = Toggle encryption capability
+#. *   a = Toggle authentication capability
+#. *   q = Finish
 #.
 msgid "SsEeAaQq"
 msgstr "SsEeAaQq"
@@ -3962,6 +3962,11 @@ msgstr "   (%d) ECC (僅能用於加密)\n"
 msgid "  (%d) Existing key\n"
 msgstr "   (%d) 現有的金鑰\n"
 
+#, fuzzy, c-format
+#| msgid "   (%d) Existing key from card\n"
+msgid "  (%d) Existing key from card\n"
+msgstr "   (%d) 卡片上現存的金鑰\n"
+
 msgid "Enter the keygrip: "
 msgstr "請輸入金鑰鑰柄: "
 
@@ -3972,6 +3977,17 @@ msgid "No key with this keygrip\n"
 msgstr "沒有金鑰有此金鑰鑰柄\n"
 
 #, c-format
+msgid "error reading the card: %s\n"
+msgstr "讀取卡片時出錯: %s\n"
+
+#, c-format
+msgid "Serial number of the card: %s\n"
+msgstr "卡片序號: %s\n"
+
+msgid "Available keys:\n"
+msgstr "可用金鑰:\n"
+
+#, c-format
 msgid "rounded to %u bits\n"
 msgstr "加大到 %u 位元\n"
 
@@ -4678,6 +4694,11 @@ msgid "Note: signatures using the %s algorithm are rejected\n"
 msgstr "請注意: 採用 %s 演算法的簽章已遭駁回\n"
 
 #, fuzzy, c-format
+#| msgid "Note: signatures using the %s algorithm are rejected\n"
+msgid "Note: third-party key signatures using the %s algorithm are rejected\n"
+msgstr "請注意: 採用 %s 演算法的簽章已遭駁回\n"
+
+#, fuzzy, c-format
 #| msgid "%s:%u: read error: %s\n"
 msgid "(reported error: %s)\n"
 msgstr "%s:%u: 讀取錯誤: %s\n"
@@ -6770,17 +6791,6 @@ msgid "   (%d) Existing key from card\n"
 msgstr "   (%d) 卡片上現存的金鑰\n"
 
 #, c-format
-msgid "error reading the card: %s\n"
-msgstr "讀取卡片時出錯: %s\n"
-
-#, c-format
-msgid "Serial number of the card: %s\n"
-msgstr "卡片序號: %s\n"
-
-msgid "Available keys:\n"
-msgstr "可用金鑰:\n"
-
-#, c-format
 msgid "Possible actions for a %s key:\n"
 msgstr "%s 金鑰可能的動作:\n"
 
@@ -8808,6 +8818,18 @@ msgstr ""
 "語法: gpg-check-pattern [選項] 樣式檔案\n"
 "用樣式檔案來檢查由標準輸入給定的密語\n"
 
+#~ msgid "male"
+#~ msgstr "男性"
+
+#~ msgid "female"
+#~ msgstr "女性"
+
+#~ msgid "unspecified"
+#~ msgstr "未特定"
+
+#~ msgid "Sex ((M)ale, (F)emale or space): "
+#~ msgstr "性別 ((M)男性, (F)女性或留空): "
+
 #~ msgid "no keyserver known (use option --keyserver)\n"
 #~ msgstr "沒有已知的金鑰伺服器 (使用 --keyserver 選項)\n"
 
index 0f38e7c..9371932 100644 (file)
@@ -308,8 +308,10 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
     int special;
   } table[] = {
     { "$AUTHKEYID",   1 },
-    { "NKS-VERSION",  2 },
-    { "CHV-STATUS",   3 },
+    { "$ENCRKEYID",   2 },
+    { "$SIGNKEYID",   3 },
+    { "NKS-VERSION",  4 },
+    { "CHV-STATUS",   5 },
     { NULL, 0 }
   };
   gpg_error_t err = 0;
@@ -339,13 +341,27 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
       }
       break;
 
-    case 2: /* NKS-VERSION */
+    case 2: /* $ENCRKEYID */
+      {
+        char const tmp[] = "NKS-NKS3.45B1";
+        send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0);
+      }
+      break;
+
+    case 3: /* $SIGNKEYID */
+      {
+        char const tmp[] = "NKS-NKS3.4531";
+        send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0);
+      }
+      break;
+
+    case 4: /* NKS-VERSION */
       snprintf (buffer, sizeof buffer, "%d", app->app_local->nks_version);
       send_status_info (ctrl, table[idx].name,
                         buffer, strlen (buffer), NULL, 0);
       break;
 
-    case 3: /* CHV-STATUS */
+    case 5: /* CHV-STATUS */
       {
         /* Returns: PW1.CH PW2.CH PW1.CH.SIG PW2.CH.SIG That are the
            two global passwords followed by the two SigG passwords.
@@ -385,6 +401,7 @@ do_learn_status_core (app_t app, ctrl_t ctrl, unsigned int flags, int is_sigg)
   char ct_buf[100], id_buf[100];
   int i;
   const char *tag;
+  const char *usage;
 
   if (is_sigg)
     tag = "SIGG";
@@ -434,9 +451,19 @@ do_learn_status_core (app_t app, ctrl_t ctrl, unsigned int flags, int is_sigg)
             {
               snprintf (id_buf, sizeof id_buf, "NKS-%s.%04X",
                         tag, filelist[i].fid);
+              if (filelist[i].issignkey && filelist[i].isenckey)
+                usage = "sae";
+              else if (filelist[i].issignkey)
+                usage = "sa";
+              else if (filelist[i].isenckey)
+                usage = "e";
+              else
+                usage = "";
+
               send_status_info (ctrl, "KEYPAIRINFO",
                                 gripstr, 40,
                                 id_buf, strlen (id_buf),
+                                usage, strlen (usage),
                                 NULL, (size_t)0);
             }
         }
index 66b7bd1..eac71a2 100644 (file)
@@ -98,7 +98,7 @@ static struct {
   { 0x0065, 1,    0, 1, 0, 0, 0, 0, "Cardholder Related Data"},
   { 0x005B, 0, 0x65, 0, 0, 0, 0, 0, "Name" },
   { 0x5F2D, 0, 0x65, 0, 0, 0, 0, 0, "Language preferences" },
-  { 0x5F35, 0, 0x65, 0, 0, 0, 0, 0, "Sex" },
+  { 0x5F35, 0, 0x65, 0, 0, 0, 0, 0, "Salutation" },
   { 0x006E, 1,    0, 1, 0, 0, 0, 0, "Application Related Data" },
   { 0x004F, 0, 0x6E, 1, 0, 0, 0, 0, "AID" },
   { 0x0073, 1,    0, 1, 0, 0, 0, 0, "Discretionary Data Objects" },
@@ -984,6 +984,8 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
     { "PRIVATE-DO-3", 0x0103 },
     { "PRIVATE-DO-4", 0x0104 },
     { "$AUTHKEYID",   0x0000, -3 },
+    { "$ENCRKEYID",   0x0000, -6 },
+    { "$SIGNKEYID",   0x0000, -7 },
     { "$DISPSERIALNO",0x0000, -4 },
     { "KDF",          0x00F9 },
     { NULL, 0 }
@@ -1065,6 +1067,18 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
         send_key_attr (ctrl, app, table[idx].name, i);
       return 0;
     }
+  if (table[idx].special == -6)
+    {
+      char const tmp[] = "OPENPGP.2";
+      send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0);
+      return 0;
+    }
+  if (table[idx].special == -7)
+    {
+      char const tmp[] = "OPENPGP.1";
+      send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0);
+      return 0;
+    }
 
   relptr = get_one_do (app, table[idx].tag, &value, &valuelen, &rc);
   if (relptr)
@@ -1779,6 +1793,7 @@ send_keypair_info (app_t app, ctrl_t ctrl, int key)
   unsigned char grip[20];
   char gripstr[41];
   char idbuf[50];
+  const char *usage;
 
   err = get_public_key (app, keyno);
   if (err)
@@ -1796,10 +1811,19 @@ send_keypair_info (app_t app, ctrl_t ctrl, int key)
 
   bin2hex (grip, 20, gripstr);
 
+  switch (keyno)
+    {
+    case 0: usage = "sc"; break;
+    case 1: usage = "e";  break;
+    case 2: usage = "sa"; break;
+    default: usage = "";  break;
+    }
+
   sprintf (idbuf, "OPENPGP.%d", keyno+1);
   send_status_info (ctrl, "KEYPAIRINFO",
                     gripstr, 40,
                     idbuf, strlen (idbuf),
+                    usage, strlen (usage),
                     NULL, (size_t)0);
 
  leave:
index d7b6b5a..466efaa 100644 (file)
@@ -1946,6 +1946,7 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
   int rc;
   int msglen;
   int notified = 0;
+  int bwi = 1;
 
   /* Fixme: The next line for the current Valgrind without support
      for USB IOCTLs. */
@@ -1956,7 +1957,7 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
   npth_unprotect ();
 #endif
   rc = libusb_bulk_transfer (handle->idev, handle->ep_bulk_in,
-                             (char*)buffer, length, &msglen, timeout);
+                             buffer, length, &msglen, bwi*timeout);
 #ifdef USE_NPTH
   npth_protect ();
 #endif
@@ -2004,6 +2005,10 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
       DEBUGOUT_2 ("time extension requested (%02X,%02X)\n",
                   buffer[7], buffer[8]);
 
+      bwi = 1;
+      if (buffer[8] != 0 && buffer[8] != 0xff)
+        bwi = buffer[8];
+
       /* Gnuk enhancement to prompt user input by ack button */
       if (buffer[8] == 0xff && !notified)
         {
@@ -2844,7 +2849,7 @@ ccid_transceive_apdu_level (ccid_driver_t handle,
   size_t apdu_part_len;
   size_t msglen;
   unsigned char seqno;
-  int bwi = 4;
+  int bwi = 0;
   unsigned char chain = 0;
 
   if (apdu_len == 0 || apdu_len > sizeof (msg) - 10)
@@ -3096,7 +3101,7 @@ ccid_transceive (ccid_driver_t handle,
           msg[0] = PC_to_RDR_XfrBlock;
           msg[5] = 0; /* slot */
           msg[6] = seqno = handle->seqno++;
-          msg[7] = 4; /* bBWI */
+          msg[7] = wait_more; /* bBWI */
           msg[8] = 0; /* RFU */
           msg[9] = 0; /* RFU */
           set_msg_len (msg, tpdulen);
@@ -3418,13 +3423,27 @@ ccid_transceive_secure (ccid_driver_t handle,
       if (handle->id_product == CRYPTOUCAN){
         pininfo->maxlen = 25;
         enable_varlen = 1;
+        break;
       }
-      break;
+      return CCID_DRIVER_ERR_NOT_SUPPORTED;
+    case VENDOR_GEMPC:
+      if (handle->id_product == GEMPC_PINPAD)
+        {
+          enable_varlen = 0;
+          pininfo->minlen = 4;
+          pininfo->maxlen = 8;
+          break;
+        }
+      else if (handle->id_product == GEMPC_EZIO)
+        {
+          pininfo->maxlen = 25;
+          enable_varlen = 1;
+          break;
+        }
+      return CCID_DRIVER_ERR_NOT_SUPPORTED;
     default:
-      if ((handle->id_vendor == VENDOR_GEMPC &&
-           handle->id_product == GEMPC_PINPAD)
-          || (handle->id_vendor == VENDOR_VEGA &&
-              handle->id_product == VEGA_ALPHA))
+      if ((handle->id_vendor == VENDOR_VEGA &&
+           handle->id_product == VEGA_ALPHA))
         {
           enable_varlen = 0;
           pininfo->minlen = 4;
index 1550b3e..32b9475 100644 (file)
@@ -83,6 +83,7 @@ enum {
 #define VASCO_920       0x0920
 #define GEMPC_PINPAD    0x3478
 #define GEMPC_CT30      0x3437
+#define GEMPC_EZIO      0x34c2    /* (!=34c0) Also known as IDBridge CT710 */
 #define VEGA_ALPHA      0x0008
 #define CYBERJACK_GO    0x0504
 #define CRYPTOUCAN      0x81e6
index 20d879f..281e479 100644 (file)
@@ -445,7 +445,7 @@ gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
 {
   int rc;
   char line[ASSUAN_LINELENGTH];
-   membuf_t data;
+  membuf_t data;
   struct cipher_parm_s cipher_parm;
   size_t n, len;
   char *p, *buf, *endp;
@@ -496,7 +496,8 @@ gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
       return rc;
     }
 
-  put_membuf (&data, "", 1); /* Make sure it is 0 terminated. */
+  /* Make sure it is 0 terminated so we can invoke strtoul safely.  */
+  put_membuf (&data, "", 1);
   buf = get_membuf (&data, &len);
   if (!buf)
     return gpg_error (GPG_ERR_ENOMEM);
@@ -506,14 +507,20 @@ gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
     {
       if (len < 13 || memcmp (buf, "(5:value", 8) ) /* "(5:valueN:D)\0" */
         return gpg_error (GPG_ERR_INV_SEXP);
-      len -= 11;   /* Count only the data of the second part. */
-      p = buf + 8; /* Skip leading parenthesis and the value tag. */
+      /* Trim any spurious trailing Nuls: */
+      while (buf[len-1] == 0)
+        len--;
+      if (buf[len-1] != ')')
+        return gpg_error (GPG_ERR_INV_SEXP);
+      len--; /* Drop the final close-paren: */
+      p = buf + 8; /* Skip leading parenthesis and the value tag.  */
+      len -= 8; /* Count only the data of the second part.  */
     }
   else
     {
       /* For compatibility with older gpg-agents handle the old style
-         incomplete S-exps. */
-      len--;      /* Do not count the Nul. */
+         incomplete S-exps.  */
+      len--;      /* Do not count the Nul.  */
       p = buf;
     }
 
@@ -521,8 +528,8 @@ gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
   if (!n || *endp != ':')
     return gpg_error (GPG_ERR_INV_SEXP);
   endp++;
-  if (endp-p+n > len)
-    return gpg_error (GPG_ERR_INV_SEXP); /* Oops: Inconsistent S-Exp. */
+  if (endp-p+n != len)
+    return gpg_error (GPG_ERR_INV_SEXP); /* Oops: Inconsistent S-Exp.  */
 
   memmove (buf, endp, n);
 
@@ -753,9 +760,9 @@ scd_keypairinfo_status_cb (void *opaque, const char *line)
     {
       sl = append_to_strlist (listaddr, line);
       p = sl->d;
-      /* Make sure that we only have two tokes so that future
-         extensions of the format won't change the format expected by
-         the caller.  */
+      /* Make sure that we only have two tokens so that future
+       * extensions of the format won't change the format expected by
+       * the caller.  */
       while (*p && !spacep (p))
         p++;
       if (*p)
@@ -764,7 +771,22 @@ scd_keypairinfo_status_cb (void *opaque, const char *line)
             p++;
           while (*p && !spacep (p))
             p++;
-          *p = 0;
+          if (*p)
+            {
+              *p++ = 0;
+              while (spacep (p))
+                p++;
+              while (*p && !spacep (p))
+                {
+                  switch (*p++)
+                    {
+                    case 'c': sl->flags |= GCRY_PK_USAGE_CERT; break;
+                    case 's': sl->flags |= GCRY_PK_USAGE_SIGN; break;
+                    case 'e': sl->flags |= GCRY_PK_USAGE_ENCR; break;
+                    case 'a': sl->flags |= GCRY_PK_USAGE_AUTH; break;
+                    }
+                }
+            }
         }
     }
 
@@ -774,7 +796,7 @@ scd_keypairinfo_status_cb (void *opaque, const char *line)
 
 /* Call the agent to read the keypairinfo lines of the current card.
    The list is returned as a string made up of the keygrip, a space
-   and the keyid.  */
+   and the keyid.  The flags of the string carry the usage bits.  */
 int
 gpgsm_agent_scd_keypairinfo (ctrl_t ctrl, strlist_t *r_list)
 {
@@ -789,7 +811,7 @@ gpgsm_agent_scd_keypairinfo (ctrl_t ctrl, strlist_t *r_list)
   inq_parm.ctrl = ctrl;
   inq_parm.ctx = agent_ctx;
 
-  rc = assuan_transact (agent_ctx, "SCD LEARN --force",
+  rc = assuan_transact (agent_ctx, "SCD LEARN --keypairinfo",
                         NULL, NULL,
                         default_inq_cb, &inq_parm,
                         scd_keypairinfo_status_cb, &list);
index bbc74a5..d75b017 100644 (file)
@@ -249,6 +249,7 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, estream_t output_stream)
               gcry_sexp_t s_pkey;
               char *algostr = NULL;
               const char *keyref;
+              int any = 0;
 
               keyref = strchr (sl->d, ' ');
               if (keyref)
@@ -257,12 +258,33 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, estream_t output_stream)
                   if (!gpgsm_agent_readkey (ctrl, 1, keyref, &pkey))
                     {
                       if (!gcry_sexp_new (&s_pkey, pkey, 0, 0))
-                        algostr = pubkey_algo_string (s_pkey);
+                        algostr = pubkey_algo_string (s_pkey, NULL);
                       gcry_sexp_release (s_pkey);
                     }
                   xfree (pkey);
                 }
-              tty_printf ("   (%d) %s %s\n", count, sl->d, algostr);
+              tty_printf ("   (%d) %s %s", count, sl->d, algostr);
+              if ((sl->flags & GCRY_PK_USAGE_CERT))
+                {
+                  tty_printf ("%scert", any?",":" (");
+                  any = 1;
+                }
+              if ((sl->flags & GCRY_PK_USAGE_SIGN))
+                {
+                  tty_printf ("%ssign", any?",":" (");
+                  any = 1;
+                }
+              if ((sl->flags & GCRY_PK_USAGE_AUTH))
+                {
+                  tty_printf ("%sauth", any?",":" (");
+                  any = 1;
+                }
+              if ((sl->flags & GCRY_PK_USAGE_ENCR))
+                {
+                  tty_printf ("%sencr", any?",":" (");
+                  any = 1;
+                }
+              tty_printf ("%s\n", any?")":"");
               xfree (algostr);
             }
           xfree (answer);
index 60ed14a..db0768e 100644 (file)
@@ -75,10 +75,10 @@ prepare_decryption (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
     log_printhex ("pkcs1 encoded session key:", seskey, seskeylen);
 
   n=0;
-  if (seskeylen == 24 || seskeylen == 16)
+  if (seskeylen == 32 || seskeylen == 24 || seskeylen == 16)
     {
-      /* Smells like a 3-DES or AES-128 key.  This might happen
-       * because a SC has already done the unpacking.  A better
+      /* Smells like an AES-128, 3-DES, or AES-256 key.  This might
+       * happen because a SC has already done the unpacking.  A better
        * solution would be to test for this only after we triggered
        * the GPG_ERR_INV_SESSION_KEY. */
     }
index 94c5beb..8fe953e 100644 (file)
                "no-auto-key-retrieve"
                "no-auto-key-locate"
               "allow-weak-digest-algos"
+               "allow-weak-key-signatures"
                "ignore-mdc-error"
               (if have-opt-always-trust
                   "no-auto-check-trustdb" "#no-auto-check-trustdb")
index 1ba2423..5dfec85 100644 (file)
@@ -1279,7 +1279,7 @@ gc_component_launch (int component)
                  gc_component[component].name);
       if (!opt.quiet)
         log_info (_("Note: Use the command \"%s%s\" to get details.\n"),
-                  "gpgconf --check-options ", gc_component[component].name);
+                  gc_component[component].name, " --gpgconf-test");
       gpgconf_failure (0);
     }
 
index 29e9248..52c89ba 100644 (file)
@@ -21,6 +21,7 @@
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <unistd.h>
 
 #include "../common/util.h"
 #include "../common/status.h"
@@ -867,6 +868,81 @@ wks_compute_hu_fname (char **r_fname, const char *addrspec)
 }
 
 
+/* Make sure that a policy file exists for addrspec.  Directories must
+ * already exist.  */
+static gpg_error_t
+ensure_policy_file (const char *addrspec)
+{
+  gpg_error_t err;
+  const char *domain;
+  char *fname;
+  estream_t fp;
+
+  domain = strchr (addrspec, '@');
+  if (!domain || !domain[1] || domain == addrspec)
+    return gpg_error (GPG_ERR_INV_ARG);
+  domain++;
+
+  /* Create the filename.  */
+  fname = make_filename_try (opt.directory, domain, "policy", NULL);
+  err = fname? 0 : gpg_error_from_syserror ();
+  if (err)
+    goto leave;
+
+  /* First a quick check whether it already exists.  */
+  if (!access (fname, F_OK))
+    {
+      err = 0; /* File already exists.  */
+      goto leave;
+    }
+  err = gpg_error_from_syserror ();
+  if (gpg_err_code (err) == GPG_ERR_ENOENT)
+    err = 0;
+  else
+    {
+      log_error ("domain %s: problem with '%s': %s\n",
+                 domain, fname, gpg_strerror (err));
+      goto leave;
+    }
+
+  /* Now create the file.  */
+  fp = es_fopen (fname, "wxb");
+  if (!fp)
+    {
+      err = gpg_error_from_syserror ();
+      if (gpg_err_code (err) == GPG_ERR_EEXIST)
+        err = 0; /* Was created between the access() and fopen().  */
+      else
+        log_error ("domain %s: error creating '%s': %s\n",
+                   domain, fname, gpg_strerror (err));
+      goto leave;
+    }
+
+  es_fprintf (fp, "# Policy flags for domain %s\n", domain);
+  if (es_ferror (fp) || es_fclose (fp))
+    {
+      err = gpg_error_from_syserror ();
+      log_error ("error writing '%s': %s\n", fname, gpg_strerror (err));
+      goto leave;
+    }
+
+  if (opt.verbose)
+    log_info ("policy file '%s' created\n", fname);
+
+  /* Make sure the policy file world readable.  */
+  if (gnupg_chmod (fname, "-rw-rw-r--"))
+    {
+      err = gpg_error_from_syserror ();
+      log_error ("can't set permissions of '%s': %s\n",
+                 fname, gpg_strerror (err));
+      goto leave;
+    }
+
+ leave:
+  xfree (fname);
+  return err;
+}
+
 
 /* Helper form wks_cmd_install_key.  */
 static gpg_error_t
@@ -1040,6 +1116,12 @@ wks_cmd_install_key (const char *fname, const char *userid)
   if (err)
     goto leave;
 
+  /* Now that wks_compute_hu_fname has created missing directories we
+   * can create a policy file if it does not exist.  */
+  err = ensure_policy_file (addrspec);
+  if (err)
+    goto leave;
+
   /* Publish.  */
   err = write_to_file (fp, huname);
   if (err)
@@ -1056,6 +1138,7 @@ wks_cmd_install_key (const char *fname, const char *userid)
   if (!opt.quiet)
     log_info ("key %s published for '%s'\n", fpr, addrspec);
 
+
  leave:
   xfree (huname);
   free_uidinfo_list (uidlist);