Imported Upstream version 2.1.7 upstream/2.1.7
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 9 Feb 2021 07:00:02 +0000 (16:00 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 9 Feb 2021 07:00:02 +0000 (16:00 +0900)
88 files changed:
.gitignore
NEWS
agent/agent.h
agent/command.c
agent/cvt-openpgp.c
agent/findkey.c
build-aux/git-hooks/commit-msg
common/asshelp.h
common/audit.c
common/homedir.c
common/i18n.c
common/iobuf.c
common/logging.h
common/membuf.h
common/mischelp.h
common/openpgp-oid.c
common/stringhelp.c
common/stringhelp.h
common/types.h
common/util.h
configure.ac
dirmngr/ks-engine-ldap.c
dirmngr/ks-engine.h
doc/DETAILS
doc/HACKING
doc/Makefile.am
doc/gpg-agent.texi
doc/gpg.texi
doc/gpgv.texi
doc/howto-create-a-server-cert.texi
doc/tools.texi
g10/call-agent.c
g10/call-agent.h
g10/card-util.c
g10/ecdh.c
g10/getkey.c
g10/gpgv.c
g10/import.c
g10/keydb.c
g10/keydb.h
g10/keyedit.c
g10/keygen.c
g10/keyid.c
g10/keylist.c
g10/main.h
g10/mainproc.c
g10/parse-packet.c
g10/pkglue.c
g10/pubkey-enc.c
g13/g13.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/Makefile.am
scd/app-openpgp.c
scd/card-common.h [deleted file]
scd/card-dinsig.c [deleted file]
scd/card-p15.c [deleted file]
scd/card.c [deleted file]
scd/pcsc-wrapper.c [deleted file]
scd/sc-copykeys.c [deleted file]
scd/scdaemon.h
sm/gpgsm.h
tools/Makefile.am
tools/gpgsm-gencert.sh [deleted file]

index a525f14..dd3d031 100644 (file)
@@ -67,7 +67,6 @@ doc/gpg-zip.1
 doc/gpg2.1
 doc/gpgconf.1
 doc/gpgparsemail.1
-doc/gpgsm-gencert.sh.1
 doc/gpgsm.1
 doc/gpgv2.1
 doc/scdaemon.1
diff --git a/NEWS b/NEWS
index 37d8728..8a2db79 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,28 @@
+Noteworthy changes in version 2.1.7 (2015-08-11)
+------------------------------------------------
+
+ * gpg: Support encryption with Curve25519 if Libgcrypt 1.7 is used.
+
+ * gpg: In the --edit-key menu: Removed the need for "toggle", changed
+   how secret keys are indicated, new commands "fpr *" and "grip".
+
+ * gpg: More fixes related to legacy keys in a keyring.
+
+ * gpgv: Does now also work with a "trustedkeys.kbx" file.
+
+ * scd: Support some feature from the OpenPGP card 3.0 specs.
+
+ * scd: Improved ECC support
+
+ * agent: New option --force for the DELETE_KEY command.
+
+ * w32: Look for the Pinentry at more places.
+
+ * Dropped deprecated gpgsm-gencert.sh
+
+ * Various other bug fixes.
+
+
 Noteworthy changes in version 2.1.6 (2015-07-01)
 ------------------------------------------------
 
index 2948bff..958e3be 100644 (file)
@@ -300,6 +300,7 @@ typedef int (*lookup_ttl_t)(const char *hexgrip);
    and uses that to translate a string according to the locale set for
    the connection.  The macro LunderscoreIMPL is used by i18n to
    actually define the inline function when needed.  */
+#ifdef ENABLE_NLS
 #define L_(a) agent_Lunderscore (ctrl, (a))
 #define LunderscorePROTO                                            \
   static inline const char *agent_Lunderscore (ctrl_t ctrl,         \
@@ -312,10 +313,14 @@ typedef int (*lookup_ttl_t)(const char *hexgrip);
     return ctrl? i18n_localegettext (ctrl->lc_messages, string) \
       /*     */: gettext (string);                              \
   }
+#else
+#define L_(a) (a)
+#endif
 
 
 /*-- gpg-agent.c --*/
-void agent_exit (int rc) GPGRT_GCC_A_NR; /* Also implemented in other tools */
+void agent_exit (int rc)
+                GPGRT_ATTR_NORETURN; /* Also implemented in other tools */
 gpg_error_t agent_copy_startup_env (ctrl_t ctrl);
 const char *get_agent_socket_name (void);
 const char *get_agent_ssh_socket_name (void);
@@ -328,10 +333,10 @@ int map_pk_openpgp_to_gcry (int openpgp_algo);
 /*-- command.c --*/
 gpg_error_t agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid);
 gpg_error_t agent_write_status (ctrl_t ctrl, const char *keyword, ...)
-     GNUPG_GCC_A_SENTINEL(0);
+     GPGRT_ATTR_SENTINEL(0);
 gpg_error_t agent_print_status (ctrl_t ctrl, const char *keyword,
                                 const char *format, ...)
-     GPGRT_GCC_A_PRINTF(3,4);
+     GPGRT_ATTR_PRINTF(3,4);
 void bump_key_eventcounter (void);
 void bump_card_eventcounter (void);
 void start_command_handler (ctrl_t, gnupg_fd_t, gnupg_fd_t);
@@ -381,7 +386,7 @@ gpg_error_t agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip,
                                       int *r_keytype,
                                       unsigned char **r_shadow_info);
 gpg_error_t agent_delete_key (ctrl_t ctrl, const char *desc_text,
-                              const unsigned char *grip);
+                              const unsigned char *grip, int force);
 
 /*-- call-pinentry.c --*/
 void initialize_module_call_pinentry (void);
index a69abc5..62a4628 100644 (file)
@@ -2388,27 +2388,29 @@ cmd_export_key (assuan_context_t ctx, char *line)
 
 \f
 static const char hlp_delete_key[] =
-  "DELETE_KEY <hexstring_with_keygrip>\n"
+  "DELETE_KEY [--force] <hexstring_with_keygrip>\n"
   "\n"
   "Delete a secret key from the key store.\n"
-  "As safeguard the agent asks the user for confirmation.\n";
+  "Unless --force is used the agent asks the user for confirmation.\n";
 static gpg_error_t
 cmd_delete_key (assuan_context_t ctx, char *line)
 {
   ctrl_t ctrl = assuan_get_pointer (ctx);
   gpg_error_t err;
+  int force;
   unsigned char grip[20];
 
   if (ctrl->restricted)
     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
 
+  force = has_option (line, "--force");
   line = skip_options (line);
 
   err = parse_keygrip (ctx, line, grip);
   if (err)
     goto leave;
 
-  err = agent_delete_key (ctrl, ctrl->server_local->keydesc, grip);
+  err = agent_delete_key (ctrl, ctrl->server_local->keydesc, grip, force );
   if (err)
     goto leave;
 
index 562179b..8bf5873 100644 (file)
@@ -83,14 +83,19 @@ get_keygrip (int pubkey_algo, const char *curve, gcry_mpi_t *pkey,
     case GCRY_PK_ECC:
       if (!curve)
         err = gpg_error (GPG_ERR_BAD_SECKEY);
-      else if (!strcmp (curve, openpgp_curve_to_oid ("Ed25519", NULL)))
-        err = gcry_sexp_build (&s_pkey, NULL,
-                               "(public-key(ecc(curve %s)(flags eddsa)(q%m)))",
-                               "Ed25519", pkey[0]);
       else
-        err = gcry_sexp_build (&s_pkey, NULL,
-                               "(public-key(ecc(curve %s)(q%m)))",
-                               curve, pkey[0]);
+        {
+          const char *format;
+
+          if (!strcmp (curve, "Ed25519"))
+            format = "(public-key(ecc(curve %s)(flags eddsa)(q%m)))";
+          else if (!strcmp (curve, "Curve25519"))
+            format = "(public-key(ecc(curve %s)(flags djb-tweak)(q%m)))";
+          else
+            format = "(public-key(ecc(curve %s)(q%m)))";
+
+          err = gcry_sexp_build (&s_pkey, NULL, format, curve, pkey[0]);
+        }
       break;
 
     default:
@@ -146,19 +151,21 @@ convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey,
     case GCRY_PK_ECC:
       if (!curve)
         err = gpg_error (GPG_ERR_BAD_SECKEY);
-      else if (!strcmp (curve, openpgp_curve_to_oid ("Ed25519", NULL)))
+      else
         {
-          /* Do not store the OID as name but the real name and the
-             EdDSA flag.  */
-          err = gcry_sexp_build (&s_skey, NULL,
-                                 "(private-key(ecc(curve%s)(flags eddsa)"
-                                 "(q%m)(d%m)))",
-                                 "Ed25519", skey[0], skey[1]);
+          const char *format;
+
+          if (!strcmp (curve, "Ed25519"))
+            /* Do not store the OID as name but the real name and the
+               EdDSA flag.  */
+            format = "(private-key(ecc(curve %s)(flags eddsa)(q%m)(d%m)))";
+          else if (!strcmp (curve, "Curve25519"))
+            format = "(private-key(ecc(curve %s)(flags djb-tweak)(q%m)(d%m)))";
+          else
+            format = "(private-key(ecc(curve %s)(q%m)(d%m)))";
+
+          err = gcry_sexp_build (&s_skey, NULL, format, curve, skey[0], skey[1]);
         }
-      else
-        err = gcry_sexp_build (&s_skey, NULL,
-                               "(private-key(ecc(curve%s)(q%m)(d%m)))",
-                               curve, skey[0], skey[1]);
       break;
 
     default:
@@ -216,22 +223,24 @@ convert_transfer_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey,
     case GCRY_PK_ECC:
       if (!curve)
         err = gpg_error (GPG_ERR_BAD_SECKEY);
-      else if (!strcmp (curve, openpgp_curve_to_oid ("Ed25519", NULL)))
+      else
         {
-          /* Do not store the OID as name but the real name and the
-             EdDSA flag.  */
-          err = gcry_sexp_build
-            (&s_skey, NULL,
-             "(protected-private-key(ecc(curve%s)(flags eddsa)(q%m)"
-             "(protected openpgp-native%S)))",
-             "Ed25519", skey[0], transfer_key);
+          const char *format;
+
+          if (!strcmp (curve, "Ed25519"))
+            /* Do not store the OID as name but the real name and the
+               EdDSA flag.  */
+            format = "(protected-private-key(ecc(curve %s)(flags eddsa)(q%m)"
+              "(protected openpgp-native%S)))";
+          else if (!strcmp (curve, "Curve25519"))
+            format = "(protected-private-key(ecc(curve %s)(flags djb-tweak)(q%m)"
+              "(protected openpgp-native%S)))";
+          else
+            format = "(protected-private-key(ecc(curve %s)(q%m)"
+              "(protected openpgp-native%S)))";
+
+          err = gcry_sexp_build (&s_skey, NULL, format, curve, skey[0], transfer_key);
         }
-      else
-        err = gcry_sexp_build
-          (&s_skey, NULL,
-           "(protected-private-key(ecc(curve%s)(q%m)"
-           "(protected openpgp-native%S)))",
-           curve, skey[0], transfer_key);
       break;
 
     default:
index 1ca7f04..e7cd79e 100644 (file)
@@ -1219,14 +1219,18 @@ agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip,
 
 \f
 /* Delete the key with GRIP from the disk after having asked for
-   confirmation using DESC_TEXT.  Common error codes are:
+   confirmation using DESC_TEXT.  If FORCE is set the fucntion won't
+   require a confirmation via Pinentry or warns if the key is also
+   used by ssh.
+
+   Common error codes are:
      GPG_ERR_NO_SECKEY
      GPG_ERR_KEY_ON_CARD
      GPG_ERR_NOT_CONFIRMED
 */
 gpg_error_t
 agent_delete_key (ctrl_t ctrl, const char *desc_text,
-                  const unsigned char *grip)
+                  const unsigned char *grip, int force)
 {
   gpg_error_t err;
   gcry_sexp_t s_skey = NULL;
@@ -1253,57 +1257,57 @@ agent_delete_key (ctrl_t ctrl, const char *desc_text,
     case PRIVATE_KEY_CLEAR:
     case PRIVATE_KEY_OPENPGP_NONE:
     case PRIVATE_KEY_PROTECTED:
-      {
-        bin2hex (grip, 20, hexgrip);
-        if (!desc_text)
-          {
-            default_desc = xtryasprintf
-           (L_("Do you really want to delete the key identified by keygrip%%0A"
-               "  %s%%0A  %%C%%0A?"), hexgrip);
-            desc_text = default_desc;
-          }
-
-        /* Note, that we will take the comment as a C string for
-           display purposes; i.e. all stuff beyond a Nul character is
-           ignored.  */
+      bin2hex (grip, 20, hexgrip);
+      if (!force)
         {
-          gcry_sexp_t comment_sexp;
-
-          comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
-          if (comment_sexp)
-            comment = gcry_sexp_nth_string (comment_sexp, 1);
-          gcry_sexp_release (comment_sexp);
-        }
+          if (!desc_text)
+            {
+              default_desc = xtryasprintf
+          (L_("Do you really want to delete the key identified by keygrip%%0A"
+              "  %s%%0A  %%C%%0A?"), hexgrip);
+              desc_text = default_desc;
+            }
 
-       if (desc_text)
-          err = modify_description (desc_text, comment? comment:"", s_skey,
-                                    &desc_text_final);
-       if (err)
-          goto leave;
-
-        err = agent_get_confirmation (ctrl, desc_text_final,
-                                      L_("Delete key"), L_("No"), 0);
-        if (err)
-          goto leave;
-
-        cf = ssh_open_control_file ();
-        if (cf)
+          /* Note, that we will take the comment as a C string for
+             display purposes; i.e. all stuff beyond a Nul character is
+             ignored.  */
           {
-            if (!ssh_search_control_file (cf, hexgrip, NULL, NULL, NULL))
-              {
-                err = agent_get_confirmation
-                  (ctrl,
-                   L_("Warning: This key is also listed for use with SSH!\n"
-                      "Deleting the key might remove your ability to "
-                      "access remote machines."),
-                   L_("Delete key"), L_("No"), 0);
-                if (err)
-                  goto leave;
-              }
+            gcry_sexp_t comment_sexp;
+
+            comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
+            if (comment_sexp)
+              comment = gcry_sexp_nth_string (comment_sexp, 1);
+            gcry_sexp_release (comment_sexp);
           }
 
-        err = remove_key_file (grip);
-      }
+          if (desc_text)
+            err = modify_description (desc_text, comment? comment:"", s_skey,
+                                      &desc_text_final);
+          if (err)
+            goto leave;
+
+          err = agent_get_confirmation (ctrl, desc_text_final,
+                                        L_("Delete key"), L_("No"), 0);
+          if (err)
+            goto leave;
+
+          cf = ssh_open_control_file ();
+          if (cf)
+            {
+              if (!ssh_search_control_file (cf, hexgrip, NULL, NULL, NULL))
+                {
+                  err = agent_get_confirmation
+                    (ctrl,
+                     L_("Warning: This key is also listed for use with SSH!\n"
+                        "Deleting the key might remove your ability to "
+                        "access remote machines."),
+                     L_("Delete key"), L_("No"), 0);
+                  if (err)
+                    goto leave;
+                }
+            }
+        }
+      err = remove_key_file (grip);
       break;
 
     case PRIVATE_KEY_SHADOWED:
index 5a697c7..3ca918b 100755 (executable)
@@ -86,11 +86,17 @@ sub check_msg($$)
   2 <= @line && length $line[1]
     and return 'second line must be empty';
 
+  # See git-commit(1), this is the --cleanup=scissors option. Everything
+  # after and including this line gets ignored.
+  my $marker = '# ------------------------ >8 ------------------------';
+
   # Limit line length to allow for the ChangeLog's leading TAB.
   foreach my $line (@line)
     {
       72 < length $line && $line =~ /^[^#]/
         and return 'line longer than 72 characters';
+
+      last if $line eq $marker;
     }
 
   return '';
index c685564..6a52172 100644 (file)
@@ -81,11 +81,11 @@ start_new_dirmngr (assuan_context_t *r_ctx,
 gpg_error_t print_assuan_status (assuan_context_t ctx,
                                  const char *keyword,
                                  const char *format,
-                                 ...) GPGRT_GCC_A_PRINTF(3,4);
+                                 ...) GPGRT_ATTR_PRINTF(3,4);
 gpg_error_t vprint_assuan_status (assuan_context_t ctx,
                                   const char *keyword,
                                   const char *format,
-                                  va_list arg_ptr) GPGRT_GCC_A_PRINTF(3,0);
+                                  va_list arg_ptr) GPGRT_ATTR_PRINTF(3,0);
 
 
 #endif /*GNUPG_COMMON_ASSHELP_H*/
index 9ed5708..198b8e6 100644 (file)
@@ -72,11 +72,11 @@ struct audit_ctx_s
 
 \f
 static void writeout_para (audit_ctx_t ctx,
-                           const char *format, ...) GPGRT_GCC_A_PRINTF(2,3);
+                           const char *format, ...) GPGRT_ATTR_PRINTF(2,3);
 static void writeout_li (audit_ctx_t ctx, const char *oktext,
-                         const char *format, ...) GPGRT_GCC_A_PRINTF(3,4);
+                         const char *format, ...) GPGRT_ATTR_PRINTF(3,4);
 static void writeout_rem (audit_ctx_t ctx,
-                          const char *format, ...) GPGRT_GCC_A_PRINTF(2,3);
+                          const char *format, ...) GPGRT_ATTR_PRINTF(2,3);
 
 
 /* Add NAME to the list of help tags.  NAME needs to be a const string
index 8c73e99..3918693 100644 (file)
@@ -613,6 +613,26 @@ dirmngr_user_socket_name (void)
 static const char *
 get_default_pinentry_name (int reset)
 {
+  static struct {
+    const char *(*rfnc)(void);
+    const char *name;
+  } names[] = {
+    /* The first entry is what we return in case we found no
+       other pinentry.  */
+    { gnupg_bindir, DIRSEP_S "pinentry" EXEEXT_S },
+#ifdef HAVE_W32_SYSTEM
+    /* Try Gpg4win directory (with bin and without.) */
+    { w32_rootdir, "\\..\\Gpg4win\\bin\\pinentry.exe" },
+    { w32_rootdir, "\\..\\Gpg4win\\pinentry.exe" },
+    /* Try old Gpgwin directory.  */
+    { w32_rootdir, "\\..\\GNU\\GnuPG\\pinentry.exe" },
+    /* Try a Pinentry from the common GNU dir.  */
+    { w32_rootdir, "\\..\\GNU\\bin\\pinentry.exe" },
+#endif
+    /* Last chance is a pinentry-basic (which comes with the
+       GnuPG 2.1 Windows installer).  */
+    { gnupg_bindir, DIRSEP_S "pinentry-basic" EXEEXT_S }
+  };
   static char *name;
 
   if (reset)
@@ -623,22 +643,27 @@ get_default_pinentry_name (int reset)
 
   if (!name)
     {
-      name = xstrconcat (gnupg_bindir (),
-                         DIRSEP_S "pinentry" EXEEXT_S, NULL);
-      if (access (name, F_OK) && errno == ENOENT)
+      int i;
+
+      for (i=0; i < DIM(names); i++)
         {
           char *name2;
-          name2 = xstrconcat (gnupg_bindir (),
-                              DIRSEP_S "pinentry-basic" EXEEXT_S, NULL);
-          if (access (name2, F_OK))
-            xfree (name2); /* Does not exist.  */
-          else /* Switch to pinentry-basic.  */
+
+          name2 = xstrconcat (names[i].rfnc (), names[i].name, NULL);
+          if (!access (name2, F_OK))
             {
+              /* Use that pinentry.  */
               xfree (name);
               name = name2;
+              break;
             }
+          if (!i) /* Store the first as fallback return.  */
+            name = name2;
+          else
+            xfree (name2);
         }
     }
+
   return name;
 }
 
index d1f157c..39e3d8f 100644 (file)
 #include "i18n.h"
 
 
-/* An object to store pointers to static strings and there static
-   translation.  A linked list is not optimal but given that we only
+#undef USE_MSGCACHE
+#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) \
+   && !defined(USE_SIMPLE_GETTEXT) && defined(ENABLE_NLS)
+# define USE_MSGCACHE 1
+#endif
+
+
+#ifdef USE_MSGCACHE
+/* An object to store pointers to static strings and their static
+   translations.  A linked list is not optimal but given that we only
    have a few dozen messages it should be acceptable. */
 struct msg_cache_s
 {
@@ -67,6 +75,7 @@ struct msg_cache_heads_s
    static strings.  */
 static struct msg_cache_heads_s *msgcache;
 
+#endif /*USE_MSGCACHE*/
 
 
 void
@@ -153,8 +162,7 @@ i18n_utf8 (const char *string)
 const char *
 i18n_localegettext (const char *lc_messages, const char *string)
 {
-#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES)             \
-  && !defined(USE_SIMPLE_GETTEXT) && defined(ENABLE_NLS)
+#if USE_MSGCACHE
   const char *result = NULL;
   char *saved = NULL;
   struct msg_cache_heads_s *mh;
@@ -220,8 +228,10 @@ i18n_localegettext (const char *lc_messages, const char *string)
   xfree (saved);
   return result? result : _(string);
 
-#else /*!(HAVE_SETLOCALE && LC_MESSAGES ...)*/
+#else /*!USE_MSGCACHE*/
+
   (void)lc_messages;
   return _(string);
-#endif /*!(HAVE_SETLOCALE && LC_MESSAGES ...)*/
+
+#endif /*!USE_MSGCACHE*/
 }
index ca74bd7..284408b 100644 (file)
@@ -138,6 +138,13 @@ typedef struct
 #define OP_MIN_PARTIAL_CHUNK     512
 #define OP_MIN_PARTIAL_CHUNK_2POW 9
 
+enum
+  {
+    BLOCK_FILTER_INPUT=1,
+    BLOCK_FILTER_OUTPUT=2,
+    BLOCK_FILTER_TEMP=3
+  };
+
 /* The context we use for the block filter (used to handle OpenPGP
    length information header).  */
 typedef struct
@@ -994,7 +1001,7 @@ block_filter (void *opaque, int control, iobuf_t chain, byte * buffer,
        log_debug ("init block_filter %p\n", a);
       if (a->partial)
        a->count = 0;
-      else if (a->use == 1)
+      else if (a->use == BLOCK_FILTER_INPUT)
        a->count = a->size = 0;
       else
        a->count = a->size;     /* force first length bytes */
@@ -1008,7 +1015,7 @@ block_filter (void *opaque, int control, iobuf_t chain, byte * buffer,
     }
   else if (control == IOBUFCTRL_FREE)
     {
-      if (a->use == 2)
+      if (a->use == BLOCK_FILTER_OUTPUT)
        {                       /* write the end markers */
          if (a->partial)
            {
@@ -1096,10 +1103,13 @@ iobuf_print_chain (iobuf_t a)
   return 0;
 }
 
-/****************
- * Allocate a new io buffer, with no function assigned.
- * Use is the desired usage: 1 for input, 2 for output, 3 for temp buffer
- * BUFSIZE is a suggested buffer size.
+/* Allocate a new io buffer, with no function assigned.
+
+   USE is the desired usage: BLOCK_FILTER_INPUT for input,
+   BLOCK_FILTER_OUTPUT for output, or BLOCK_FILTER_TEMP for a temp
+   buffer.
+
+   BUFSIZE is a suggested buffer size.
  */
 iobuf_t
 iobuf_alloc (int use, size_t bufsize)
@@ -1107,6 +1117,10 @@ iobuf_alloc (int use, size_t bufsize)
   iobuf_t a;
   static int number = 0;
 
+  assert (use == BLOCK_FILTER_INPUT
+         || use == BLOCK_FILTER_OUTPUT
+         || use == BLOCK_FILTER_TEMP);
+
   a = xcalloc (1, sizeof *a);
   a->use = use;
   a->d.buf = xmalloc (bufsize);
@@ -1137,7 +1151,7 @@ iobuf_close (iobuf_t a)
   for (; a && !rc; a = a2)
     {
       a2 = a->chain;
-      if (a->use == 2 && (rc = iobuf_flush (a)))
+      if (a->use == BLOCK_FILTER_OUTPUT && (rc = iobuf_flush (a)))
        log_error ("iobuf_flush failed on close: %s\n", gpg_strerror (rc));
 
       if (DBG_IOBUF)
@@ -1167,7 +1181,7 @@ iobuf_cancel (iobuf_t a)
   char *remove_name = NULL;
 #endif
 
-  if (a && a->use == 2)
+  if (a && a->use == BLOCK_FILTER_OUTPUT)
     {
       s = iobuf_get_real_fname (a);
       if (s && *s)
@@ -1610,7 +1624,7 @@ iobuf_push_filter2 (iobuf_t a,
   if (a->directfp)
     BUG ();
 
-  if (a->use == 2 && (rc = iobuf_flush (a)))
+  if (a->use == BLOCK_FILTER_OUTPUT && (rc = iobuf_flush (a)))
     return rc;
 
   if (a->subno >= MAX_NESTING_FILTER)
@@ -1635,10 +1649,11 @@ iobuf_push_filter2 (iobuf_t a,
   a->filter_ov = NULL;
   a->filter_ov_owner = 0;
   a->filter_eof = 0;
-  if (a->use == 3)
-    a->use = 2;                        /* make a write stream from a temp stream */
+  if (a->use == BLOCK_FILTER_TEMP)
+    /* make a write stream from a temp stream */
+    a->use = BLOCK_FILTER_OUTPUT;
 
-  if (a->use == 2)
+  if (a->use == BLOCK_FILTER_OUTPUT)
     {                          /* allocate a fresh buffer for the
                                    original stream */
       b->d.buf = xmalloc (a->d.size);
@@ -1717,7 +1732,7 @@ pop_filter (iobuf_t a, int (*f) (void *opaque, int control,
     log_bug ("pop_filter(): filter function not found\n");
 
   /* flush this stream if it is an output stream */
-  if (a->use == 2 && (rc = iobuf_flush (b)))
+  if (a->use == BLOCK_FILTER_OUTPUT && (rc = iobuf_flush (b)))
     {
       log_error ("iobuf_flush failed in pop_filter: %s\n", gpg_strerror (rc));
       return rc;
@@ -1776,7 +1791,7 @@ underflow (iobuf_t a)
   int rc;
 
   assert (a->d.start == a->d.len);
-  if (a->use == 3)
+  if (a->use == BLOCK_FILTER_TEMP)
     return -1;                 /* EOF because a temp buffer can't do an underflow */
 
   if (a->filter_eof)
@@ -1838,7 +1853,7 @@ underflow (iobuf_t a)
 /*         if( a->no == 1 ) */
 /*                   log_hexdump ("     data:", a->d.buf, len); */
        }
-      if (a->use == 1 && rc == -1)
+      if (a->use == BLOCK_FILTER_INPUT && rc == -1)
        {                       /* EOF: we can remove the filter */
          size_t dummy_len = 0;
 
@@ -1900,7 +1915,7 @@ iobuf_flush (iobuf_t a)
   if (a->directfp)
     return 0;
 
-  if (a->use == 3)
+  if (a->use == BLOCK_FILTER_TEMP)
     {                          /* increase the temp buffer */
       unsigned char *newbuf;
       size_t newsize = a->d.size + IOBUF_BUFFER_SIZE;
@@ -1915,7 +1930,7 @@ iobuf_flush (iobuf_t a)
       a->d.size = newsize;
       return 0;
     }
-  else if (a->use != 2)
+  else if (a->use != BLOCK_FILTER_OUTPUT)
     log_bug ("flush on non-output iobuf\n");
   else if (!a->filter)
     log_bug ("iobuf_flush: no filter\n");
@@ -2331,7 +2346,7 @@ iobuf_seek (iobuf_t a, off_t newpos)
        }
       clearerr (fp);
     }
-  else if (a->use != 3)  /* Not a temp stream.  */
+  else if (a->use != BLOCK_FILTER_TEMP)
     {
       for (; a; a = a->chain)
        {
@@ -2358,8 +2373,9 @@ iobuf_seek (iobuf_t a, off_t newpos)
        }
 #endif
     }
-  if (a->use != 3)
-    a->d.len = 0;      /* Discard the buffer  unless it is a temp stream.  */
+  /* Discard the buffer unless it is a temp stream.  */
+  if (a->use != BLOCK_FILTER_TEMP)
+    a->d.len = 0;
   a->d.start = 0;
   a->nbytes = 0;
   a->nlimit = 0;
@@ -2438,11 +2454,11 @@ iobuf_set_partial_block_mode (iobuf_t a, size_t len)
 {
   block_filter_ctx_t *ctx = xcalloc (1, sizeof *ctx);
 
-  assert (a->use == 1 || a->use == 2);
+  assert (a->use == BLOCK_FILTER_INPUT || a->use == BLOCK_FILTER_OUTPUT);
   ctx->use = a->use;
   if (!len)
     {
-      if (a->use == 1)
+      if (a->use == BLOCK_FILTER_INPUT)
        log_debug ("pop_filter called in set_partial_block_mode"
                   " - please report\n");
       pop_filter (a, block_filter, NULL);
index 0bd1a6c..dbfc8ba 100644 (file)
@@ -48,8 +48,9 @@ int log_test_fd (int fd);
 int  log_get_fd(void);
 estream_t log_get_stream (void);
 
-#ifdef GPGRT_GCC_M_FUNCTION
-  void bug_at( const char *file, int line, const char *func ) GPGRT_GCC_A_NR;
+#ifdef GPGRT_HAVE_MACRO_FUNCTION
+  void bug_at (const char *file, int line, const char *func)
+               GPGRT_ATTR_NORETURN;
 # define BUG() bug_at( __FILE__ , __LINE__, __FUNCTION__ )
 #else
   void bug_at( const char *file, int line );
@@ -74,17 +75,17 @@ enum jnlib_log_levels {
     GPGRT_LOG_BUG,
     GPGRT_LOG_DEBUG
 };
-void log_log (int level, const char *fmt, ...) GPGRT_GCC_A_PRINTF(2,3);
+void log_log (int level, const char *fmt, ...) GPGRT_ATTR_PRINTF(2,3);
 void log_logv (int level, const char *fmt, va_list arg_ptr);
 void log_string (int level, const char *string);
 
 
-void log_bug( const char *fmt, ... )   GPGRT_GCC_A_NR_PRINTF(1,2);
-void log_fatal( const char *fmt, ... ) GPGRT_GCC_A_NR_PRINTF(1,2);
-void log_error( const char *fmt, ... ) GPGRT_GCC_A_PRINTF(1,2);
-void log_info( const char *fmt, ... )  GPGRT_GCC_A_PRINTF(1,2);
-void log_debug( const char *fmt, ... ) GPGRT_GCC_A_PRINTF(1,2);
-void log_printf( const char *fmt, ... ) GPGRT_GCC_A_PRINTF(1,2);
+void log_bug (const char *fmt, ...)    GPGRT_ATTR_NR_PRINTF(1,2);
+void log_fatal (const char *fmt, ...)  GPGRT_ATTR_NR_PRINTF(1,2);
+void log_error (const char *fmt, ...)  GPGRT_ATTR_PRINTF(1,2);
+void log_info (const char *fmt, ...)   GPGRT_ATTR_PRINTF(1,2);
+void log_debug (const char *fmt, ...)  GPGRT_ATTR_PRINTF(1,2);
+void log_printf (const char *fmt, ...) GPGRT_ATTR_PRINTF(1,2);
 void log_flush (void);
 
 /* Print a hexdump of BUFFER.  With TEXT passes as NULL print just the
index 32d4f90..eb7d565 100644 (file)
@@ -55,7 +55,7 @@ void clear_membuf (membuf_t *mb, size_t amount);
 void put_membuf  (membuf_t *mb, const void *buf, size_t len);
 void put_membuf_str (membuf_t *mb, const char *string);
 void put_membuf_printf (membuf_t *mb, const char *format,
-                        ...) GPGRT_GCC_A_PRINTF(2,3);
+                        ...) GPGRT_ATTR_PRINTF(2,3);
 void *get_membuf (membuf_t *mb, size_t *len);
 void *get_membuf_shrink (membuf_t *mb, size_t *len);
 const void *peek_membuf (membuf_t *mb, size_t *len);
index ecbf38b..cd72a4a 100644 (file)
@@ -48,27 +48,32 @@ time_t timegm (struct tm *tm);
 #define DIMof(type,member)   DIM(((type *)0)->member)
 
 
-#undef GPGRT_GCC_HAVE_PUSH_PRAGMA
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
-# define GPGRT_GCC_M_FUNCTION 1  /* __FUNCTION__ macro is available.  */
-# define GPGRT_GCC_A_NR             __attribute__ ((noreturn))
-# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4 )
-#   define GPGRT_GCC_HAVE_PUSH_PRAGMA 1
-#   define GPGRT_GCC_A_PRINTF( f, a ) \
-                    __attribute__ ((format (__gnu_printf__,f,a)))
-#   define GPGRT_GCC_A_NR_PRINTF( f, a ) \
-                   __attribute__ ((noreturn, format (__gnu_printf__,f,a)))
+/* Replacements for macros not available with libgpg-error < 1.20.  */
+#ifndef GPGRT_GCC_VERSION
+
+# undef GPGRT_HAVE_PRAGMA_GCC_PUSH
+# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
+#  define GPGRT_HAVE_MACRO_FUNCTION 1  /* __FUNCTION__ macro is available.  */
+#  define GPGRT_ATTR_NORETURN  __attribute__ ((noreturn))
+#  if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4 )
+#    define GPGRT_HAVE_PRAGMA_GCC_PUSH 1
+#    define GPGRT_ATTR_PRINTF(f,a) \
+                  __attribute__ ((format (__gnu_printf__,f,a)))
+#    define GPGRT_ATTR_NR_PRINTF(f,a) \
+                  __attribute__ ((noreturn, format (__gnu_printf__,f,a)))
+#  else
+#    define GPGRT_ATTR_PRINTF(f, a) \
+                  __attribute__ ((format (printf,f,a)))
+#    define GPGRT_ATTR_NR_PRINTF(f, a) \
+                  __attribute__ ((noreturn, format (printf,f,a)))
+#  endif
 # else
-#   define GPGRT_GCC_A_PRINTF( f, a )  __attribute__ ((format (printf,f,a)))
-#   define GPGRT_GCC_A_NR_PRINTF( f, a ) \
-                           __attribute__ ((noreturn, format (printf,f,a)))
+#  define GPGRT_ATTR_NORETURN
+#  define GPGRT_ATTR_PRINTF( f, a )
+#  define GPGRT_ATTR_NR_PRINTF( f, a )
 # endif
-#else
-# define GPGRT_GCC_A_NR
-# define GPGRT_GCC_A_PRINTF( f, a )
-# define GPGRT_GCC_A_NR_PRINTF( f, a )
-#endif
 
+#endif /*Older libgpg-error.  */
 
 /* To avoid that a compiler optimizes certain memset calls away, these
    macros may be used instead. */
index 7a75801..8a964a4 100644 (file)
@@ -45,6 +45,7 @@ static struct {
   const char *alias;  /* NULL or alternative name of the curve.  */
 } oidtable[] = {
 
+  { "Curve25519",      "1.3.6.1.4.1.3029.1.5.1", 255, "cv25519" },
   { "Ed25519",         "1.3.6.1.4.1.11591.15.1", 255, "ed25519" },
 
   { "NIST P-256",      "1.2.840.10045.3.1.7",    256, "nistp256" },
@@ -65,6 +66,10 @@ static struct {
 static const char oid_ed25519[] =
   { 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, 0x47, 0x0f, 0x01 };
 
+/* The OID for Curve25519 in OpenPGP format.  */
+static const char oid_crv25519[] =
+  { 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01 };
+
 
 /* Helper for openpgp_oid_from_str.  */
 static size_t
@@ -291,6 +296,22 @@ openpgp_oid_is_ed25519 (gcry_mpi_t a)
 }
 
 
+int
+openpgp_oid_is_crv25519 (gcry_mpi_t a)
+{
+  const unsigned char *buf;
+  unsigned int nbits;
+  size_t n;
+
+  if (!a || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
+    return 0;
+
+  buf = gcry_mpi_get_opaque (a, &nbits);
+  n = (nbits+7)/8;
+  return (n == DIM (oid_crv25519)
+          && !memcmp (buf, oid_crv25519, DIM (oid_crv25519)));
+}
+
 
 /* Map the Libgcrypt ECC curve NAME to an OID.  If R_NBITS is not NULL
    store the bit size of the curve there.  Returns NULL for unknown
@@ -332,22 +353,22 @@ openpgp_curve_to_oid (const char *name, unsigned int *r_nbits)
 }
 
 
-/* Map an OpenPGP OID to the Libgcrypt curve NAME.  Returns "?" for
-   unknown curve names.  We prefer an alias name here which is more
-   suitable for printing.  */
+/* Map an OpenPGP OID to the Libgcrypt curve NAME.  Returns NULL for
+   unknown curve names.  Unless CANON is set we prefer an alias name
+   here which is more suitable for printing.  */
 const char *
-openpgp_oid_to_curve (const char *oidstr)
+openpgp_oid_to_curve (const char *oidstr, int canon)
 {
   int i;
 
   if (!oidstr)
-    return "";
+    return NULL;
 
   for (i=0; oidtable[i].name; i++)
     if (!strcmp (oidtable[i].oidstr, oidstr))
-      return oidtable[i].alias? oidtable[i].alias : oidtable[i].name;
+      return !canon && oidtable[i].alias? oidtable[i].alias : oidtable[i].name;
 
-  return "?";
+  return NULL;
 }
 
 
index 6714eb8..576c2ea 100644 (file)
@@ -493,7 +493,13 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr)
 
   xfree (home_buffer);
   for (argc=0; argv[argc]; argc++)
-    p = stpcpy (stpcpy (p, "/"), argv[argc]);
+    {
+      /* Avoid a leading double slash if the first part was "/".  */
+      if (!argc && name[0] == '/' && !name[1])
+        p = stpcpy (p, argv[argc]);
+      else
+        p = stpcpy (stpcpy (p, "/"), argv[argc]);
+    }
 
   if (want_abs)
     {
@@ -543,7 +549,13 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr)
               memcpy (home_buffer, p, p - name + 1);
               p = home_buffer + (p - name + 1);
             }
-          strcpy (stpcpy (stpcpy (p, home), "/"), name);
+
+          /* Avoid a leading double slash if the cwd is "/".  */
+          if (home[0] == '/' && !home[1])
+            strcpy (stpcpy (p, "/"), name);
+          else
+            strcpy (stpcpy (stpcpy (p, home), "/"), name);
+
           xfree (name);
           name = home_buffer;
           /* Let's do a simple compression to catch the most common
index ab16d16..a84c81b 100644 (file)
@@ -52,11 +52,11 @@ size_t length_sans_trailing_ws (const unsigned char *line, size_t len);
 
 char *make_basename(const char *filepath, const char *inputpath);
 char *make_dirname(const char *filepath);
-char *make_filename( const char *first_part, ... ) GNUPG_GCC_A_SENTINEL(0);
-char *make_filename_try (const char *first_part, ... ) GNUPG_GCC_A_SENTINEL(0);
-char *make_absfilename (const char *first_part, ...) GNUPG_GCC_A_SENTINEL(0);
+char *make_filename( const char *first_part, ... ) GPGRT_ATTR_SENTINEL(0);
+char *make_filename_try (const char *first_part, ... ) GPGRT_ATTR_SENTINEL(0);
+char *make_absfilename (const char *first_part, ...) GPGRT_ATTR_SENTINEL(0);
 char *make_absfilename_try (const char *first_part,
-                            ...) GNUPG_GCC_A_SENTINEL(0);
+                            ...) GPGRT_ATTR_SENTINEL(0);
 int compare_filenames( const char *a, const char *b );
 
 int hextobyte (const char *s);
@@ -139,9 +139,9 @@ char *try_percent_escape (const char *str, const char *extra);
 /* Concatenate the string S1 with all the following strings up to a
    NULL.  Returns a malloced buffer with the new string or NULL on a
    malloc error or if too many arguments are given.  */
-char *strconcat (const char *s1, ...) GNUPG_GCC_A_SENTINEL(0);
+char *strconcat (const char *s1, ...) GPGRT_ATTR_SENTINEL(0);
 /* Ditto, but die on error.  */
-char *xstrconcat (const char *s1, ...) GNUPG_GCC_A_SENTINEL(0);
+char *xstrconcat (const char *s1, ...) GPGRT_ATTR_SENTINEL(0);
 
 char **strsplit (char *string, char delim, char replacement, int *count);
 
index 8d7730b..2bb817f 100644 (file)
 #endif
 
 
-/* Some GCC attributes.  Note that we use also define some in
-   mischelp.h, but this header and types.h are not always included.
-   Should eventually be put into one file (e.g. nlib-common.h).  */
-#if __GNUC__ >= 4
-# define GNUPG_GCC_A_SENTINEL(a) __attribute__ ((sentinel(a)))
-#else
-# define GNUPG_GCC_A_SENTINEL(a)
+/* Some GCC attributes.  These are replacements for libgpg-error < 1.20.  */
+#ifndef GPGRT_GCC_VERSION
+# if __GNUC__ >= 4
+#  define GPGRT_ATTR_SENTINEL(a) __attribute__ ((sentinel(a)))
+# else
+#  define GPGRT_ATTR_SENTINEL(a)
+# endif
 #endif
 
 #endif /*GNUPG_COMMON_TYPES_H*/
index b92d78c..66749ea 100644 (file)
 #define snprintf gpgrt_snprintf
 
 
-/* GCC attributes.  */
-#ifndef GNUPG_GCC_ATTR_FORMAT_ARG
-#if __GNUC__ >= 3 /* Actually 2.8 but testing the major is easier.  */
-# define GNUPG_GCC_ATTR_FORMAT_ARG(a)  __attribute__ ((__format_arg__ (a)))
-#else
-# define GNUPG_GCC_ATTR_FORMAT_ARG(a)
-#endif
-#endif
+/* Replacements for macros not available with libgpg-error < 1.20.  */
+#ifndef GPGRT_GCC_VERSION
 
-#if __GNUC__ >= 4
-# define GNUPG_GCC_A_SENTINEL(a) __attribute__ ((sentinel(a)))
-#else
-# define GNUPG_GCC_A_SENTINEL(a)
-#endif
+# ifndef GPGRT_ATTR_FORMAT_ARG
+# if __GNUC__ >= 3 /* Actually 2.8 but testing the major is easier.  */
+#  define GPGRT_ATTR_FORMAT_ARG(a)  __attribute__ ((__format_arg__ (a)))
+# else
+#  define GPGRT_ATTR_FORMAT_ARG(a)
+# endif
+# endif
 
-#if __GNUC__ >= 4
-# define GNUPG_GCC_A_USED __attribute__ ((used))
-#else
-# define GNUPG_GCC_A_USED
-#endif
+# if __GNUC__ >= 4
+#  define GPGRT_ATTR_SENTINEL(a) __attribute__ ((sentinel(a)))
+# else
+#  define GPGRT_ATTR_SENTINEL(a)
+# endif
+
+# if __GNUC__ >= 4
+#  define GPGRT_ATTR_USED __attribute__ ((used))
+# else
+#  define GPGRT_ATTR_USED
+# endif
+
+#endif /*libgpg-error < 1.20 */
 
 
 /* We need this type even if we are not using libreadline and or we
@@ -318,8 +322,9 @@ size_t percent_unescape_inplace (char *string, int nulrepl);
 gpg_error_t openpgp_oid_from_str (const char *string, gcry_mpi_t *r_mpi);
 char *openpgp_oid_to_str (gcry_mpi_t a);
 int openpgp_oid_is_ed25519 (gcry_mpi_t a);
+int openpgp_oid_is_crv25519 (gcry_mpi_t a);
 const char *openpgp_curve_to_oid (const char *name, unsigned int *r_nbits);
-const char *openpgp_oid_to_curve (const char *oid);
+const char *openpgp_oid_to_curve (const char *oid, int canon);
 const char *openpgp_enum_curves (int *idxp);
 
 
@@ -371,9 +376,9 @@ const char *gnupg_messages_locale_name (void);
 void setup_libgcrypt_logging (void);
 
 /* Same as estream_asprintf but die on memory failure.  */
-char *xasprintf (const char *fmt, ...) GPGRT_GCC_A_PRINTF(1,2);
+char *xasprintf (const char *fmt, ...) GPGRT_ATTR_PRINTF(1,2);
 /* This is now an alias to estream_asprintf.  */
-char *xtryasprintf (const char *fmt, ...) GPGRT_GCC_A_PRINTF(1,2);
+char *xtryasprintf (const char *fmt, ...) GPGRT_ATTR_PRINTF(1,2);
 
 /* Replacement for gcry_cipher_algo_name.  */
 const char *gnupg_cipher_algo_name (int algo);
index cf49647..b38aa06 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], [1])
-m4_define([mym4_micro], [6])
+m4_define([mym4_micro], [7])
 
 # 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 4288119..1b8ef03 100644 (file)
@@ -1404,7 +1404,7 @@ modlist_lookup (LDAPMod **modlist, const char *attr)
 
 /* Dump a modlist to a file.  This is useful for debugging.  */
 static estream_t modlist_dump (LDAPMod **modlist, estream_t output)
-  GNUPG_GCC_A_USED;
+  GPGRT_ATTR_USED;
 
 static estream_t
 modlist_dump (LDAPMod **modlist, estream_t output)
index 985167a..aff6cf4 100644 (file)
@@ -26,7 +26,7 @@
 /*-- ks-action.c --*/
 gpg_error_t ks_print_help (ctrl_t ctrl, const char *text);
 gpg_error_t ks_printf_help (ctrl_t ctrl, const char *format,
-                            ...) GPGRT_GCC_A_PRINTF(2,3);
+                            ...) GPGRT_ATTR_PRINTF(2,3);
 
 /*-- ks-engine-hkp.c --*/
 gpg_error_t ks_hkp_resolve (ctrl_t ctrl, parsed_uri_t uri);
index d1f7394..eb889c9 100644 (file)
@@ -408,12 +408,15 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
     - <sig-class>
     - [ <primary-key-fpr> ]
 
-    This status indicates that the signature is good. This is the same
-    as GOODSIG but has the fingerprint as the argument. Both status
-    lines are emitted for a good signature.  All arguments here are on
-    one long line.  sig-timestamp is the signature creation time in
-    seconds after the epoch. expire-timestamp is the signature
-    expiration time in seconds after the epoch (zero means "does not
+    This status indicates that the signature is cryptographically
+    valid. This is similar to GOODSIG, EXPSIG, EXPKEYSIG, or REVKEYSIG
+    (depending on the date and the state of the signature and signing
+    key) but has the fingerprint as the argument. Multiple status
+    lines (VALIDSIG and the other appropriate *SIG status) are emitted
+    for a valid signature.  All arguments here are on one long line.
+    sig-timestamp is the signature creation time in seconds after the
+    epoch. expire-timestamp is the signature expiration time in
+    seconds after the epoch (zero means "does not
     expire"). sig-version, pubkey-algo, hash-algo, and sig-class (a
     2-byte hex value) are all straight from the signature packet.
     PRIMARY-KEY-FPR is the fingerprint of the primary key or identical
@@ -421,8 +424,8 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
     key without running gpg again for this purpose.
 
     The primary-key-fpr parameter is used for OpenPGP and not
-    class is not defined for CMS and currently set to 0 and 00.
     available for CMS signatures.  The sig-version as well as the sig
+    class is not defined for CMS and currently set to 0 and 00.
 
     Note, that *-TIMESTAMP may either be a number of seconds since
     Epoch or an ISO 8601 string which can be detected by the presence
index f60f15d..c1cd348 100644 (file)
@@ -44,6 +44,17 @@ Fix type in a comment
 The marker line here is important; without it the first line would
 appear in the ChangeLog.
 
+If you exceptionally need to have longer lines in a commit log you may
+do this after this scissor line:
+#+begin_example
+# ------------------------ >8 ------------------------
+#+end_example
+(hash, blank, 24 dashes, blank, scissor, blank, 24 dashes).
+Note that such a comment will be removed if the git commit option
+=--cleanup=scissor= is used.
+
+
+
 ** License policy
 
   GnuPG is licensed under the GPLv3+ with some files under a mixed
@@ -60,8 +71,8 @@ appear in the ChangeLog.
   file "DCO".  (Except for a slight wording change, this DCO is
   identical to the one used by the Linux kernel.)
 
-  If your want to contribute code or documentation to GnuPG and you
-  didn't signed a copyright assignment with the FSF in the past, you
+  If you want to contribute code or documentation to GnuPG and you
+  didn't sign a copyright assignment with the FSF in the past, you
   need to take these simple steps:
 
   - Decide which mail address you want to use.  Please have your real
index 3ea19ad..3ed3057 100644 (file)
@@ -71,7 +71,7 @@ myman_sources = gnupg7.texi gpg.texi gpgsm.texi gpg-agent.texi \
 myman_pages   = gpg2.1 gpgsm.1 gpg-agent.1 dirmngr.8 scdaemon.1 gpgv2.1 \
                 watchgnupg.1 gpgconf.1 addgnupghome.8 gpg-preset-passphrase.1 \
                gpg-connect-agent.1 gpgparsemail.1 symcryptrun.1 \
-               gpgsm-gencert.sh.1 applygnupgdefaults.8 gpg-zip.1 \
+               applygnupgdefaults.8 gpg-zip.1 \
                dirmngr-client.1
 
 man_MANS = $(myman_pages) gnupg.7
index 4c47072..62d23bb 100644 (file)
@@ -403,6 +403,17 @@ installation dependent.  With the default configuration the name of
 the default pinentry is @file{pinentry}; if that file does not exist
 but a @file{pinentry-basic} exist the latter is used.
 
+On a Windows platform the default is to use the first existing program
+from this list:
+@file{bin\pinentry.exe},
+@file{..\Gpg4win\bin\pinentry.exe},
+@file{..\Gpg4win\pinentry.exe},
+@file{..\GNU\GnuPG\pinentry.exe},
+@file{..\GNU\bin\pinentry.exe},
+@file{bin\pinentry-basic.exe}
+where the file names are relative to the GnuPG installation directory.
+
+
 @item --pinentry-touch-file @var{filename}
 @opindex pinentry-touch-file
 By default the filename of the socket gpg-agent is listening for
index 6c5cc5d..86726b3 100644 (file)
@@ -818,7 +818,7 @@ create a signature of any type desired.
 
   @item toggle
   @opindex keyedit:toggle
-  Toggle between public and secret key listing.
+  This is dummy command which exists only for backward compatibility.
 
   @item clean
   @opindex keyedit:clean
@@ -2468,7 +2468,8 @@ The same %-expandos used for notation data are available here as well.
 @opindex set-filename
 Use @code{string} as the filename which is stored inside messages.
 This overrides the default, which is to use the actual filename of the
-file being encrypted.
+file being encrypted.  Using the empty string for @var{string}
+effectively removes the filename from the output.
 
 @item --for-your-eyes-only
 @itemx --no-for-your-eyes-only
@@ -2943,7 +2944,7 @@ helper script is provided to create these files (@pxref{addgnupghome}).
 
 For internal purposes @command{@gpgname} creates and maintains a few other
 files; They all live in in the current home directory (@pxref{option
---homedir}).  Only the @command{@gpgname} may modify these files.
+--homedir}).  Only the @command{@gpgname} program may modify these files.
 
 
 @table @file
index 8d7164a..6bcbc0a 100644 (file)
@@ -67,7 +67,8 @@ no configuration files and only a few options are implemented.
 That does also mean that it does not check for expired or revoked
 keys.
 
-By default a keyring named @file{trustedkeys.gpg} is used.  This
+By default a keyring named @file{trustedkeys.kbx} is used; if that
+does not exist a keyring named @file{trustedkeys.gpg} is used.  The
 default keyring is assumed to be in the home directory of GnuPG,
 either the default home directory or the one set by an option or an
 environment variable.  The option @code{--keyring} may be used to
index ce6dd2f..496c9ee 100644 (file)
@@ -7,18 +7,17 @@ actually been done this way to get a certificate from CAcert to be used
 on a real server.  It has only been tested with this CA, but there
 shouldn't be any problem to run this against any other CA.
 
-Before you start, make sure that gpg-agent is running.  As there is no
-need for a configuration file, you may simply enter:
+We start by generating an X.509 certificate signing request. As there
+is no need for a configuration file, you may simply enter:
 
 @cartouche
 @example
-  $ gpgsm-gencert.sh >a.p10
-  Key type
-   [1] RSA
-   [2] Existing key
-   [3] Direct from card
-  Your selection: 1
-  You selected: RSA
+  $ gpgsm --gen-key >example.com.cert-req.pem
+  Please select what kind of key you want:
+     (1) RSA
+     (2) Existing key
+     (3) Existing key from card
+  Your selection? 1
 @end example
 @end cartouche
 
@@ -32,39 +31,36 @@ Let's continue:
 
 @cartouche
 @example
-  Key length
-   [1] 1024
-   [2] 2048
-  Your selection: 1
-  You selected: 1024
+  What keysize do you want? (2048)
+  Requested keysize is 2048 bits
 @end example
 @end cartouche
 
-The script offers  two common key sizes. With the current setup of
-CAcert, it does not make much sense to use a 2k key; their policies need
-to be revised anyway (a CA root key valid for 30 years is not really
-serious).
+Hitting enter chooses the default RSA key size of 2048 bits.  Smaller
+keys are too weak on the modern Internet.  If you choose a larger
+(stronger) key, your server will need to do more work.
 
 @cartouche
 @example
-  Key usage
-   [1] sign, encrypt
-   [2] sign
-   [3] encrypt
-  Your selection: 1
-  You selected: sign, encrypt
+  Possible actions for a RSA key:
+     (1) sign, encrypt
+     (2) sign
+     (3) encrypt
+  Your selection? 1
 @end example
 @end cartouche
 
-We want to sign and encrypt using this key. This is just a suggestion
-and the CA may actually assign other key capabilities.
+Selecting ``sign'' enables use of the key for Diffie-Hellman key
+exchange mechanisms (DHE and ECDHE) in TLS, which are preferred
+because they offer forward secrecy.  Selecting ``encrypt'' enables RSA
+key exchange mechanisms, which are still common in some places.
+Selecting both enables both key exchange mechanisms.
 
 Now for some real data:
 
 @cartouche
 @example
-  Name (DN)
-  > CN=kerckhoffs.g10code.com
+  Enter the X.509 subject name: CN=example.com
 @end example
 @end cartouche
 
@@ -74,13 +70,13 @@ server names later.
 
 @cartouche
 @example
-  E-Mail addresses (end with an empty line)
+  E-Mail addresses (end with an empty line):
   > 
 @end example
 @end cartouche
 
-We don't need email addresses in a server certificate and CAcert would
-anyway ignore such a request. Thus just hit enter.
+We don't need email addresses in a TLS server certificate and CAcert
+would anyway ignore such a request. Thus just hit enter.
 
 If you want to create a client certificate for email encryption, this
 would be the place to enter your mail address
@@ -89,22 +85,21 @@ however the CA may not accept them all or reject the entire request.
 
 @cartouche
 @example
-  DNS Names (optional; end with an empty line)
-  > www.g10code.com
-  DNS Names (optional; end with an empty line)
-  > ftp.g10code.com
-  DNS Names (optional; end with an empty line)
+  Enter DNS names (optional; end with an empty line):
+  > example.com
+  > www.example.com
   > 
 @end example
 @end cartouche
 
-Here I entered the names of the servers which actually run on the
-machine given in the DN above. The browser will accept a certificate for
-any of these names. As usual the CA must approve all of these names.
+Here I entered the names of the services which the machine actually
+provides.  You almost always want to include the canonical name here
+too. The browser will accept a certificate for any of these names. As
+usual the CA must approve all of these names.
 
 @cartouche
 @example
-  URIs (optional; end with an empty line)
+  URIs (optional; end with an empty line):
   >
 @end example
 @end cartouche
@@ -112,25 +107,30 @@ any of these names. As usual the CA must approve all of these names.
 It is possible to insert arbitrary URIs into a certificate; for a server
 certificate this does not make sense.
 
+@cartouche
+@example
+  Create self-signed certificate? (y/N)
+@end example
+@end cartouche
+
+Since we are creating a certificate signing request, and not a full
+certificate, we answer no here, or just hit enter for the default.
+
 We have now entered all required information and @command{gpgsm} will
 display what it has gathered and ask whether to create the certificate
 request:
 
 @cartouche
 @example
-  Parameters for certificate request to create:
-       1       Key-Type: RSA
-       2       Key-Length: 1024
-       3       Key-Usage: sign, encrypt
-       4       Name-DN: CN=kerckhoffs.g10code.com
-       5       Name-DNS: www.g10code.com
-       6       Name-DNS: ftp.g10code.com
-  
-  Really create such a CSR?
-   [1] yes
-   [2] no
-  Your selection: 1
-  You selected: yes
+  These parameters are used:
+      Key-Type: RSA
+      Key-Length: 2048
+      Key-Usage: sign, encrypt
+      Name-DN: CN=example.com
+      Name-DNS: example.com
+      Name-DNS: www.example.com
+
+  Proceed with creation? (y/N) y
 @end example
 @end cartouche
 
@@ -146,6 +146,7 @@ When it is ready, you should see the final notice:
 @cartouche
 @example
   gpgsm: certificate request created
+  Ready.  You should now send this request to your CA.
 @end example
 @end cartouche
 
@@ -153,17 +154,22 @@ Now, you may look at the created request:
 
 @cartouche
 @example
-  $ cat a.p10
+  $ cat example.com.cert-req.pem
   -----BEGIN CERTIFICATE REQUEST-----
-  MIIBnzCCAQgCAQAwITEfMB0GA1UEAxMWa2VyY2tob2Zmcy5nMTBjb2RlLmNvbTCB
-  nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5h+uKRenpvbe+BnMY6siPO50LVyg
-  HtB7kr+YISlPJ5JAFO12yQFz9Y0sBLHbjR+V+TOawwP1dZhGjlgnEBkMdWKuEBlS
-  wFTALLX78GAyvAYAmPqSPDEYXkMECyUXVX/bbGI1bY8Y2OGy4w4D+v7e+xD2NBkm
-  Bj5cNy+YMbGVldECAwEAAaA+MDwGCSqGSIb3DQEJDjEvMC0wKwYDVR0RBCQwIoIP
-  d3d3LmcxMGNvZGUuY29tgg9mdHAuZzEwY29kZS5jb20wDQYJKoZIhvcNAQEFBQAD
-  gYEAzBRIi8KTfKyebOlMtDN6oDYBOv+r9A4w3u/Z1ikjffaiN1Bmd2o9Ez9KXKHA
-  IezLeSEA/rGUPN5Ur5qIJnRNQ8xrS+iLftr8msWQSZppVnA/vnqMrtqBUpitqAr0
-  eYBmt1Uem2Y3UFABrKPglv2xzgGkrKX6AqmFoOnJWQ0QcTw=
+  MIIClTCCAX0CAQAwFjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3
+  DQEBAQUAA4IBDwAwggEKAoIBAQDP1QEcbTvOLLCX4gAoOzH9AW7jNOMj7OSOL0uW
+  h2bCdkK5YVpnX212Z6COTC3ZG0pJiCeGt1TbbDJUlTa4syQ6JXavjK66N8ASZsyC
+  Rwcl0m6hbXp541t1dbgt2VgeGk25okWw3j+brw6zxLD2TnthJxOatID0lDIG47HW
+  GqzZmA6WHbIBIONmGnReIHTpPAPCDm92vUkpKG1xLPszuRmsQbwEl870W/FHrsvm
+  DPvVUUSdIvTV9NuRt7/WY6G4nPp9QlIuTf1ESPzIuIE91gKPdrRCAx0yuT708S1n
+  xCv3ETQ/bKPoAQ67eE3mPBqkcVwv9SE/2/36Lz06kAizRgs5AgMBAAGgOjA4Bgkq
+  hkiG9w0BCQ4xKzApMCcGA1UdEQQgMB6CC2V4YW1wbGUuY29tgg93d3cuZXhhbXBs
+  ZS5jb20wDQYJKoZIhvcNAQELBQADggEBAEWD0Qqz4OENLYp6yyO/KqF0ig9FDsLN
+  b5/R+qhms5qlhdB5+Dh+j693Sj0UgbcNKc6JT86IuBqEBZmRCJuXRoKoo5aMS1cJ
+  hXga7N9IA3qb4VBUzBWvlL92U2Iptr/cEbikFlYZF2Zv3PBv8RfopVlI3OLbKV9D
+  bJJTt/6kuoydXKo/Vx4G0DFzIKNdFdJk86o/Ziz8NOs9JjZxw9H9VY5sHKFM5LKk
+  VcLwnnLRlNjBGB+9VK/Tze575eG0cJomTp7UGIB+1xzIQVAhUZOizRDv9tHDeaK3
+  k+tUhV0kuJcYHucpJycDSrP/uAY5zuVJ0rs2QSjdnav62YrRgEsxJrU=
   -----END CERTIFICATE REQUEST-----
   $
 @end example
@@ -189,26 +195,7 @@ followed by a Ctrl-D
 @example
   -----BEGIN CERTIFICATE-----
   MIIEIjCCAgqgAwIBAgIBTDANBgkqhkiG9w0BAQQFADBUMRQwEgYDVQQKEwtDQWNl
-  cnQgSW5jLjEeMBwGA1UECxMVaHR0cDovL3d3dy5DQWNlcnQub3JnMRwwGgYDVQQD
-  ExNDQWNlcnQgQ2xhc3MgMyBSb290MB4XDTA1MTAyODE2MjA1MVoXDTA3MTAyODE2
-  MjA1MVowITEfMB0GA1UEAxMWa2VyY2tob2Zmcy5nMTBjb2RlLmNvbTCBnzANBgkq
-  hkiG9w0BAQEFAAOBjQAwgYkCgYEA5h+uKRenpvbe+BnMY6siPO50LVygHtB7kr+Y
-  ISlPJ5JAFO12yQFz9Y0sBLHbjR+V+TOawwP1dZhGjlgnEBkMdWKuEBlSwFTALLX7
-  8GAyvAYAmPqSPDEYXkMECyUXVX/bbGI1bY8Y2OGy4w4D+v7e+xD2NBkmBj5cNy+Y
-  MbGVldECAwEAAaOBtTCBsjAMBgNVHRMBAf8EAjAAMDQGA1UdJQQtMCsGCCsGAQUF
-  BwMCBggrBgEFBQcDAQYJYIZIAYb4QgQBBgorBgEEAYI3CgMDMAsGA1UdDwQEAwIF
-  oDAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLmNhY2Vy
-  dC5vcmcwKwYDVR0RBCQwIoIPd3d3LmcxMGNvZGUuY29tgg9mdHAuZzEwY29kZS5j
-  b20wDQYJKoZIhvcNAQEEBQADggIBAAj5XAHCtzQR8PV6PkQBgZqUCbcfxGO/ZIp9
-  aIT6J2z0Jo1OZI6KmConbqnZG9WyDlV5P7msQXW/Z9nBfoj4KSmNR8G/wtb8ClJn
-  W8s75+K3ZLq1UgEyxBDrS7GjtbVaj7gsfZsuiQzxmk9lbl1gbkpJ3VEMjwVCTMlM
-  fpjp8etyPhUZqOZaoKVaq//KTOsjhPMwz7TcfOkHvXketPrWTcefJQU7NKLH16D3
-  mZAwnBxp3P51H6E6VG8AoJO8xCBuVwsbXKEf/FW+tmKG9pog6CaZQ9WibROTtnKj
-  NJjSBsrUk5C+JowO/EyZRGm6R1tlok8iFXj+2aimyeBqDcxozNmFgh9F3S5u0wK0
-  6cfYgkPVMHxgwV3f3Qh+tJkgLExN7KfO9hvpZqAh+CLQtxVmvpxEVEXKR6nwBI5U
-  BaseulvVy3wUfg2daPkG17kDDBzQlsWC0BRF8anH+FWSrvseC3nS0a9g3sXF1Ic3
-  gIqeAMhkant1Ac3RR6YCWtJKr2rcQNdDAxXK35/gUSQNCi9dclEzoOgjziuA1Mha
-  94jYcvGKcwThn0iITVS5hOsCfaySBLxTzfIruLbPxXlpWuCW/6I/7YyivppKgEZU
+   [...]
   rUTFlNElRXCwIl0YcJkIaYYqWf7+A/aqYJCi8+51usZwMy3Jsq3hJ6MA3h1BgwZs
   Rtct3tIX
   -----END CERTIFICATE-----
@@ -229,19 +216,19 @@ To see the content of your certificate, you may now enter:
 
 @cartouche
 @example
-  $ gpgsm -K kerckhoffs.g10code.com
+  $ gpgsm -K example.com
   /home/foo/.gnupg/pubring.kbx
   ---------------------------
   Serial number: 4C
          Issuer: /CN=CAcert Class 3 Root/OU=http:\x2f\x2fwww.[...]
-        Subject: /CN=kerckhoffs.g10code.com
-            aka: (dns-name www.g10code.com)
-            aka: (dns-name ftp.g10code.com)
-       validity: 2005-10-28 16:20:51 through 2007-10-28 16:20:51
-       key type: 1024 bit RSA
+        Subject: /CN=example.com
+            aka: (dns-name example.com)
+            aka: (dns-name www.example.com)
+       validity: 2015-07-01 16:20:51 through 2016-07-01 16:20:51
+       key type: 2048 bit RSA
       key usage: digitalSignature keyEncipherment
   ext key usage: clientAuth (suggested), serverAuth (suggested), [...]
-    fingerprint: 0F:9C:27:B2:DA:05:5F:CB:33:19:D8:E9:65:B9:BD:4F:B1:98:CC:57
+    fingerprint: 0F:9C:27:B2:DA:05:5F:CB:33:D8:19:E9:65:B9:4F:BD:B1:98:CC:57
 @end example
 @end cartouche
 
@@ -256,7 +243,7 @@ certificate. To create such a file, run:
 
 @cartouche
 @example
-  $ gpgsm --export-secret-key-p12 -a >kerckhoffs-cert.pem
+  $ gpgsm --export-secret-key-p12 -a >example.com-cert.pem
 @end example
 @end cartouche
 
@@ -266,12 +253,12 @@ certificate as well as the private key:
 
 @cartouche
 @example
-  $ cat kerckhoffs-cert.pem
+  $ cat example-cert.pem
   Issuer ...: /CN=CAcert Class 3 Root/OU=http:\x2f\x2fwww.CA[...]
   Serial ...: 4C
-  Subject ..: /CN=kerckhoffs.g10code.com
-      aka ..: (dns-name www.g10code.com)
-      aka ..: (dns-name ftp.g10code.com)
+  Subject ..: /CN=example.com
+      aka ..: (dns-name example.com)
+      aka ..: (dns-name www.example.com)
   
   -----BEGIN PKCS12-----
   MIIHlwIBAzCCB5AGCSqGSIb37QdHAaCCB4EEggd9MIIHeTk1BJ8GCSqGSIb3DQEu
index a067eb6..1dd1b35 100644 (file)
@@ -15,7 +15,6 @@ GnuPG comes with a couple of smaller tools:
 * addgnupghome::          Create .gnupg home directories.
 * gpgconf::               Modify .gnupg home directories.
 * applygnupgdefaults::    Run gpgconf for all users.
-* gpgsm-gencert.sh::      Generate an X.509 certificate request.
 * gpg-preset-passphrase:: Put a passphrase into the cache.
 * gpg-connect-agent::     Communicate with a running agent.
 * dirmngr-client::        How to use the Dirmngr client tool.
@@ -1001,42 +1000,6 @@ applygnupgdefaults
 
 
 @c
-@c    GPGSM-GENCERT.SH
-@c
-@node gpgsm-gencert.sh
-@section Generate an X.509 certificate request
-@manpage gpgsm-gencert.sh.1
-@ifset manverb
-.B gpgsm-gencert.sh
-\- Generate an X.509 certificate request
-@end ifset
-
-@mansect synopsis
-@ifset manverb
-.B  gpgsm-gencert.sh
-@end ifset
-
-@mansect description
-This is a simple tool to interactively generate a certificate request
-which will be printed to stdout.
-
-@manpause
-@noindent
-@command{gpgsm-gencert.sh} is invoked as:
-
-@samp{gpgsm-cencert.sh}
-
-@mansect see also
-@ifset isman
-@command{gpgsm}(1),
-@command{gpg-agent}(1),
-@command{scdaemon}(1)
-@end ifset
-@include see-also-note.texi
-
-
-
-@c
 @c   GPG-PRESET-PASSPHRASE
 @c
 @node gpg-preset-passphrase
index edee66e..0df572a 100644 (file)
@@ -645,14 +645,32 @@ learn_status_cb (void *opaque, const char *line)
     }
   else if (keywordlen == 8 && !memcmp (keyword, "KEY-ATTR", keywordlen))
     {
-      int keyno, algo, nbits;
+      int keyno = 0;
+      int algo = PUBKEY_ALGO_RSA;
+      int n = 0;
 
-      sscanf (line, "%d %d %d", &keyno, &algo, &nbits);
+      sscanf (line, "%d %d %n", &keyno, &algo, &n);
       keyno--;
-      if (keyno >= 0 && keyno < DIM (parm->key_attr))
+      if (keyno < 0 || keyno >= DIM (parm->key_attr))
+        return 0;
+
+      parm->key_attr[keyno].algo = algo;
+      if (algo == PUBKEY_ALGO_RSA)
+        parm->key_attr[keyno].nbits = strtoul (line+n+3, NULL, 10);
+      else if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA
+               || algo == PUBKEY_ALGO_EDDSA)
         {
-          parm->key_attr[keyno].algo = algo;
-          parm->key_attr[keyno].nbits = nbits;
+          const char *curve;
+
+          i = 0;
+          do
+            {
+              curve = openpgp_enum_curves (&i);
+              if (!strcmp (curve, line+n))
+                break;
+            }
+          while (curve != NULL);
+          parm->key_attr[keyno].curve = curve;
         }
     }
   else if (keywordlen == 12 && !memcmp (keyword, "PRIVATE-DO-", 11)
index df570a4..70421db 100644 (file)
@@ -55,7 +55,10 @@ struct agent_card_info_s
   int chvretry[3];   /* Allowed retries for the CHV; 0 = blocked. */
   struct {           /* Array with key attributes.  */
     int algo;              /* Algorithm identifier.  */
-    unsigned int nbits;    /* Supported keysize.  */
+    union {
+      unsigned int nbits;  /* Supported keysize.  */
+      const char *curve;   /* Name of curve.  */
+    };
   } key_attr[3];
   struct {
     unsigned int ki:1;     /* Key import available.  */
index dbd530e..ed69058 100644 (file)
@@ -471,9 +471,14 @@ card_status (estream_t fp, char *serialno, size_t serialnobuflen)
 
       es_fprintf (fp, "forcepin:%d:::\n", !info.chv1_cached);
       for (i=0; i < DIM (info.key_attr); i++)
-        if (info.key_attr[0].algo)
+        if (info.key_attr[0].algo == PUBKEY_ALGO_RSA)
           es_fprintf (fp, "keyattr:%d:%d:%u:\n", i+1,
                       info.key_attr[i].algo, info.key_attr[i].nbits);
+        else if (info.key_attr[i].algo == PUBKEY_ALGO_ECDH
+                 || info.key_attr[i].algo == PUBKEY_ALGO_ECDSA
+                 || info.key_attr[i].algo == PUBKEY_ALGO_EDDSA)
+          es_fprintf (fp, "keyattr:%d:%d:%s:\n", i+1,
+                      info.key_attr[i].algo, info.key_attr[i].curve);
       es_fprintf (fp, "maxpinlen:%d:%d:%d:\n",
                   info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]);
       es_fprintf (fp, "pinretry:%d:%d:%d:\n",
@@ -553,12 +558,12 @@ card_status (estream_t fp, char *serialno, size_t serialnobuflen)
         {
           tty_fprintf (fp,    "Key attributes ...:");
           for (i=0; i < DIM (info.key_attr); i++)
-            tty_fprintf (fp, " %u%c",
-                         info.key_attr[i].nbits,
-                         info.key_attr[i].algo == 1? 'R':
-                         info.key_attr[i].algo == 17? 'D':
-                         info.key_attr[i].algo == 18? 'e':
-                         info.key_attr[i].algo == 19? 'E': '?');
+            if (info.key_attr[i].algo == PUBKEY_ALGO_RSA)
+              tty_fprintf (fp, " rsa%u", info.key_attr[i].nbits);
+            else if (info.key_attr[i].algo == PUBKEY_ALGO_ECDH
+                     || info.key_attr[i].algo == PUBKEY_ALGO_ECDSA
+                     || info.key_attr[i].algo == PUBKEY_ALGO_EDDSA)
+              tty_fprintf (fp, " %s", info.key_attr[i].curve);
           tty_fprintf (fp, "\n");
         }
       tty_fprintf (fp,    "Max. PIN lengths .: %d %d %d\n",
@@ -1332,7 +1337,7 @@ do_change_keysize (int keyno, unsigned int nbits)
   gpg_error_t err;
   char args[100];
 
-  snprintf (args, sizeof args, "--force %d 1 %u", keyno+1, nbits);
+  snprintf (args, sizeof args, "--force %d 1 rsa%u", keyno+1, nbits);
   err = agent_scd_setattr ("KEY-ATTR", args, strlen (args), NULL);
   if (err)
     log_error (_("error changing size of key %d to %u bits: %s\n"),
index 9576a1c..a1b7ecf 100644 (file)
@@ -134,9 +134,12 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
       }
 
     secret_x_size = (nbits+7)/8;
-    assert (nbytes > secret_x_size);
-    memmove (secret_x, secret_x+1, secret_x_size);
-    memset (secret_x+secret_x_size, 0, nbytes-secret_x_size);
+    assert (nbytes >= secret_x_size);
+    if ((nbytes & 1))
+      /* Remove the "04" prefix of non-compressed format.  */
+      memmove (secret_x, secret_x+1, secret_x_size);
+    if (nbytes - secret_x_size)
+      memset (secret_x+secret_x_size, 0, nbytes-secret_x_size);
 
     if (DBG_CRYPTO)
       log_printhex ("ECDH shared secret X is:", secret_x, secret_x_size );
index e450c56..3a60161 100644 (file)
@@ -2621,6 +2621,11 @@ lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, int want_secret)
       /* Release resources and continue search. */
       release_kbnode (ctx->keyblock);
       ctx->keyblock = NULL;
+      /* We need to disable the caching so that for an exact key search we
+         won't get the result back from the cache and thus end up in an
+         endless loop.  Disabling this here is sufficient because although
+         the result may have been cached, if won't be used then.  */
+      keydb_disable_caching (ctx->kr_handle);
     }
 
 found:
@@ -2633,7 +2638,8 @@ found:
       *ret_keyblock = ctx->keyblock; /* Return the keyblock.  */
       ctx->keyblock = NULL;
     }
-  else if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND && no_suitable_key)
+  else if ((gpg_err_code (rc) == GPG_ERR_NOT_FOUND
+            || gpg_err_code (rc) == GPG_ERR_LEGACY_KEY) && no_suitable_key)
     rc = want_secret? GPG_ERR_UNUSABLE_SECKEY : GPG_ERR_UNUSABLE_PUBKEY;
   else if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
     rc = want_secret? GPG_ERR_NO_SECKEY : GPG_ERR_NO_PUBKEY;
@@ -2923,6 +2929,9 @@ get_ctx_handle (GETKEY_CTX ctx)
 static void
 free_akl (struct akl *akl)
 {
+  if (! akl)
+    return;
+
   if (akl->spec)
     free_keyserver_spec (akl->spec);
 
@@ -3049,8 +3058,14 @@ have_secret_key_with_kid (u32 *keyid)
   desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
   desc.u.kid[0] = keyid[0];
   desc.u.kid[1] = keyid[1];
-  while (!result && !(err = keydb_search (kdbhd, &desc, 1, NULL)))
+  while (!result)
     {
+      err = keydb_search (kdbhd, &desc, 1, NULL);
+      if (gpg_err_code (err) == GPG_ERR_LEGACY_KEY)
+        continue;
+      if (err)
+        break;
+
       err = keydb_get_keyblock (kdbhd, &keyblock);
       if (err)
         {
@@ -3076,6 +3091,7 @@ have_secret_key_with_kid (u32 *keyid)
        }
       release_kbnode (keyblock);
     }
+
   keydb_release (kdbhd);
   return result;
 }
index 479bb95..412f4be 100644 (file)
@@ -205,8 +205,9 @@ main( int argc, char **argv )
 
   /* Note: We open all keyrings in read-only mode.  */
   if (!nrings)  /* No keyring given: use default one. */
-    keydb_add_resource ("trustedkeys" EXTSEP_S GPGEXT_GPG,
-                        KEYDB_RESOURCE_FLAG_READONLY);
+    keydb_add_resource ("trustedkeys" EXTSEP_S "kbx",
+                        (KEYDB_RESOURCE_FLAG_READONLY
+                         |KEYDB_RESOURCE_FLAG_GPGVDEF));
   for (sl = nrings; sl; sl = sl->next)
     keydb_add_resource (sl->d, KEYDB_RESOURCE_FLAG_READONLY);
 
index de22520..e92769d 100644 (file)
@@ -1414,7 +1414,9 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock,
             err = gpg_error_from_syserror ();
           else
             {
-              err = gcry_sexp_build (&curve, NULL, "(curve %s)", curvestr);
+              const char *curvename = openpgp_oid_to_curve (curvestr, 1);
+              err = gcry_sexp_build (&curve, NULL, "(curve %s)",
+                                     curvename?curvename:curvestr);
               xfree (curvestr);
               if (!err)
                 {
index 68cf832..b31c6a6 100644 (file)
@@ -434,6 +434,7 @@ keydb_add_resource (const char *url, unsigned int flags)
   int create;
   int read_only = !!(flags&KEYDB_RESOURCE_FLAG_READONLY);
   int is_default = !!(flags&KEYDB_RESOURCE_FLAG_DEFAULT);
+  int is_gpgvdef = !!(flags&KEYDB_RESOURCE_FLAG_GPGVDEF);
   int rc = 0;
   KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
   void *token;
@@ -516,6 +517,23 @@ keydb_add_resource (const char *url, unsigned int flags)
                 strcpy (filename+filenamelen-4, ".gpg");
             }
        }
+      else if (!pass && is_gpgvdef
+               && filenamelen > 4 && !strcmp (filename+filenamelen-4, ".kbx"))
+        {
+          /* Not found but gpgv's default "trustedkeys.kbx" file has
+             been requested.  We did not found it so now check whether
+             a "trustedkeys.gpg" file exists and use that instead.  */
+          KeydbResourceType rttmp;
+
+          strcpy (filename+filenamelen-4, ".gpg");
+          rttmp = rt_from_file (filename, &found, &openpgp_flag);
+          if (found
+              && ((rttmp == KEYDB_RESOURCE_TYPE_KEYBOX && openpgp_flag)
+                  || (rttmp == KEYDB_RESOURCE_TYPE_KEYRING)))
+            rt = rttmp;
+          else /* Restore filename */
+            strcpy (filename+filenamelen-4, ".kbx");
+        }
       else if (!pass
                && is_default && create
                && filenamelen > 4 && !strcmp (filename+filenamelen-4, ".gpg"))
@@ -1753,10 +1771,17 @@ keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
 gpg_error_t
 keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr)
 {
+  gpg_error_t err;
   KEYDB_SEARCH_DESC desc;
 
   memset (&desc, 0, sizeof desc);
   desc.mode = KEYDB_SEARCH_MODE_FPR;
   memcpy (desc.u.fpr, fpr, MAX_FINGERPRINT_LEN);
-  return keydb_search (hd, &desc, 1, NULL);
+  do
+    {
+      err = keydb_search (hd, &desc, 1, NULL);
+    }
+  while (gpg_err_code (err) == GPG_ERR_LEGACY_KEY);
+
+  return err;
 }
index 1aa4e0e..b64438c 100644 (file)
@@ -130,6 +130,7 @@ union pref_hint
 #define KEYDB_RESOURCE_FLAG_PRIMARY  2  /* The primary resource.  */
 #define KEYDB_RESOURCE_FLAG_DEFAULT  4  /* The default one.  */
 #define KEYDB_RESOURCE_FLAG_READONLY 8  /* Open in read only mode.  */
+#define KEYDB_RESOURCE_FLAG_GPGVDEF 16  /* Default file for gpgv.  */
 
 gpg_error_t keydb_add_resource (const char *url, unsigned int flags);
 void        keydb_dump_stats (void);
index be15b09..d8dba2d 100644 (file)
@@ -51,12 +51,13 @@ static void show_prefs (PKT_user_id * uid, PKT_signature * selfsig,
                        int verbose);
 static void show_names (estream_t fp, KBNODE keyblock, PKT_public_key * pk,
                        unsigned int flag, int with_prefs);
-static void show_key_with_all_names (estream_t fp,
+static void show_key_with_all_names (ctrl_t ctrl, estream_t fp,
                                      KBNODE keyblock, int only_marked,
                                     int with_revoker, int with_fpr,
                                     int with_subkeys, int with_prefs,
                                      int nowarn);
-static void show_key_and_fingerprint (KBNODE keyblock);
+static void show_key_and_fingerprint (kbnode_t keyblock, int with_subkeys);
+static void show_key_and_grip (kbnode_t keyblock);
 static void subkey_expire_warning (kbnode_t keyblock);
 static int menu_adduid (KBNODE keyblock, int photo, const char *photo_name,
                         const char *uidstr);
@@ -508,7 +509,7 @@ trustsig_prompt (byte * trust_value, byte * trust_depth, char **regexp)
  * function won't ask the user and use sensible defaults.
  */
 static int
-sign_uids (estream_t fp,
+sign_uids (ctrl_t ctrl, estream_t fp,
            kbnode_t keyblock, strlist_t locusr, int *ret_modified,
           int local, int nonrevocable, int trust, int interactive,
            int quick)
@@ -804,7 +805,7 @@ sign_uids (estream_t fp,
 
       /* Ask whether we really should sign these user id(s). */
       tty_fprintf (fp, "\n");
-      show_key_with_all_names (fp, keyblock, 1, 0, 1, 0, 0, 0);
+      show_key_with_all_names (ctrl, fp, keyblock, 1, 0, 1, 0, 0, 0);
       tty_fprintf (fp, "\n");
 
       if (primary_pk->expiredate && !selfsig)
@@ -1305,7 +1306,7 @@ enum cmdids
   cmdSHOWPREF,
   cmdSETPREF, cmdPREFKS, cmdNOTATION, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST,
   cmdCHKTRUST, cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, cmdCHECKBKUPKEY,
-  cmdCLEAN, cmdMINIMIZE, cmdNOP
+  cmdCLEAN, cmdMINIMIZE, cmdGRIP, cmdNOP
 };
 
 static struct
@@ -1322,6 +1323,7 @@ static struct
   { "help", cmdHELP, 0, N_("show this help")},
   { "?", cmdHELP, 0, NULL},
   { "fpr", cmdFPR, 0, N_("show key fingerprint")},
+  { "grip", cmdGRIP, 0, N_("show the keygrip")},
   { "list", cmdLIST, 0, N_("list key and user IDs")},
   { "l", cmdLIST, 0, NULL},
   { "uid", cmdSELUID, 0, N_("select user ID N")},
@@ -1366,8 +1368,7 @@ static struct
     N_("change the expiration date for the key or selected subkeys")},
   { "primary", cmdPRIMARY, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
     N_("flag the selected user ID as primary")},
-  { "toggle", cmdTOGGLE, KEYEDIT_NEED_SK,
-    N_("toggle between the secret and public key listings")},
+  { "toggle", cmdTOGGLE, KEYEDIT_NEED_SK, NULL},  /* Dummy command.  */
   { "t", cmdTOGGLE, KEYEDIT_NEED_SK, NULL},
   { "pref", cmdPREF, KEYEDIT_NOT_SK, N_("list preferences (expert)")},
   { "showpref", cmdSHOWPREF, KEYEDIT_NOT_SK, N_("list preferences (verbose)")},
@@ -1472,7 +1473,6 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
   int modified = 0;
   int sec_shadowing = 0;
   int run_subkey_warnings = 0;
-  int toggle;
   int have_commands = !!commands;
 
   if (opt.command_fd != -1)
@@ -1515,8 +1515,6 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
        tty_printf (_("Secret key is available.\n"));
     }
 
-  toggle = 0;
-
   /* Main command loop.  */
   for (;;)
     {
@@ -1529,7 +1527,8 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
 
       if (redisplay && !quiet)
        {
-         show_key_with_all_names (NULL, keyblock, 0, 1, 0, 1, 0, 0);
+          /* Show using flags: with_revoker, with_subkeys.  */
+         show_key_with_all_names (ctrl, NULL, keyblock, 0, 1, 0, 1, 0, 0);
          tty_printf ("\n");
          redisplay = 0;
        }
@@ -1616,13 +1615,6 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
              tty_printf (_("Need the secret key to do this.\n"));
              cmd = cmdNOP;
            }
-         else if (((cmds[i].flags & KEYEDIT_NOT_SK) && have_seckey && toggle)
-                  || ((cmds[i].flags & KEYEDIT_ONLY_SK) && have_seckey
-                      && !toggle))
-           {
-             tty_printf (_("Please use the command \"toggle\" first.\n"));
-             cmd = cmdNOP;
-           }
          else
            cmd = cmds[i].id;
        }
@@ -1654,7 +1646,13 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
          break;
 
        case cmdFPR:
-         show_key_and_fingerprint (keyblock);
+         show_key_and_fingerprint
+            (keyblock, (*arg_string == '*'
+                        && (!arg_string[1] || spacep (arg_string + 1))));
+         break;
+
+       case cmdGRIP:
+         show_key_and_grip (keyblock);
          break;
 
        case cmdSELUID:
@@ -1729,7 +1727,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
                break;
              }
 
-           sign_uids (NULL, keyblock, locusr, &modified,
+           sign_uids (ctrl, NULL, keyblock, locusr, &modified,
                       localsig, nonrevokesig, trustsig, interactive, 0);
          }
          break;
@@ -1743,7 +1741,6 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
              where we worked with a secret and a public keyring.  It
              is not necessary anymore but we keep this command for the
              sake of scripts using it.  */
-         toggle = !toggle;
          redisplay = 1;
          break;
 
@@ -2076,7 +2073,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
              break;
            }
 
-         show_key_with_all_names (NULL, keyblock, 0, 0, 0, 1, 0, 0);
+         show_key_with_all_names (ctrl, NULL, keyblock, 0, 0, 0, 1, 0, 0);
          tty_printf ("\n");
          if (edit_ownertrust (find_kbnode (keyblock,
                                            PKT_PUBLIC_KEY)->pkt->pkt.
@@ -2452,7 +2449,7 @@ keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids,
   /* Give some info in verbose.  */
   if (opt.verbose)
     {
-      show_key_with_all_names (es_stdout, keyblock, 0,
+      show_key_with_all_names (ctrl, es_stdout, keyblock, 0,
                                1/*with_revoker*/, 1/*with_fingerprint*/,
                                0, 0, 1);
       es_fflush (es_stdout);
@@ -2462,7 +2459,7 @@ keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids,
   if (pk->flags.revoked)
     {
       if (!opt.verbose)
-        show_key_with_all_names (es_stdout, keyblock, 0, 0, 0, 0, 0, 1);
+        show_key_with_all_names (ctrl, es_stdout, keyblock, 0, 0, 0, 0, 0, 1);
       log_error ("%s%s", _("Key is revoked."), _("  Unable to sign.\n"));
       goto leave;
     }
@@ -2493,14 +2490,14 @@ keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids,
   if (uids && !any)
     {
       if (!opt.verbose)
-        show_key_with_all_names (es_stdout, keyblock, 0, 0, 0, 0, 0, 1);
+        show_key_with_all_names (ctrl, es_stdout, keyblock, 0, 0, 0, 0, 0, 1);
       es_fflush (es_stdout);
       log_error ("%s  %s", _("No matching user IDs."), _("Nothing to sign.\n"));
       goto leave;
     }
 
   /* Sign. */
-  sign_uids (es_stdout, keyblock, locusr, &modified, local, 0, 0, 0, 1);
+  sign_uids (ctrl, es_stdout, keyblock, locusr, &modified, local, 0, 0, 0, 1);
   es_fflush (es_stdout);
 
   if (modified)
@@ -2726,12 +2723,13 @@ show_prefs (PKT_user_id * uid, PKT_signature * selfsig, int verbose)
    opt.with_colons is used.  It prints all available data in a easy to
    parse format and does not translate utf8 */
 static void
-show_key_with_all_names_colon (estream_t fp, kbnode_t keyblock)
+show_key_with_all_names_colon (ctrl_t ctrl, estream_t fp, kbnode_t keyblock)
 {
   KBNODE node;
   int i, j, ulti_hack = 0;
   byte pk_version = 0;
   PKT_public_key *primary = NULL;
+  int have_seckey;
 
   if (!fp)
     fp = es_stdout;
@@ -2752,9 +2750,13 @@ show_key_with_all_names_colon (estream_t fp, kbnode_t keyblock)
            }
 
          keyid_from_pk (pk, keyid);
+          have_seckey = !agent_probe_secret_key (ctrl, pk);
+
+          if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+            es_fputs (have_seckey? "sec:" : "pub:", fp);
+          else
+            es_fputs (have_seckey? "ssb:" : "sub:", fp);
 
-         es_fputs (node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub:" : "sub:",
-                    fp);
          if (!pk->flags.valid)
            es_putc ('i', fp);
          else if (pk->flags.revoked)
@@ -2945,20 +2947,23 @@ show_names (estream_t fp,
  * tty (ignored in with-colons mode).
  */
 static void
-show_key_with_all_names (estream_t fp,
+show_key_with_all_names (ctrl_t ctrl, estream_t fp,
                          KBNODE keyblock, int only_marked, int with_revoker,
                         int with_fpr, int with_subkeys, int with_prefs,
                          int nowarn)
 {
-  KBNODE node;
+  gpg_error_t err;
+  kbnode_t node;
   int i;
   int do_warn = 0;
+  int have_seckey = 0;
+  char *serialno = NULL;
   PKT_public_key *primary = NULL;
   char pkstrbuf[PUBKEY_STRING_SIZE];
 
   if (opt.with_colons)
     {
-      show_key_with_all_names_colon (fp, keyblock);
+      show_key_with_all_names_colon (ctrl, fp, keyblock);
       return;
     }
 
@@ -3036,13 +3041,33 @@ show_key_with_all_names (estream_t fp,
            }
 
          keyid_from_pk (pk, NULL);
-         tty_fprintf (fp, "%s%c %s/%s",
-                     node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub" :
-                     node->pkt->pkttype == PKT_PUBLIC_SUBKEY ? "sub" :
-                     node->pkt->pkttype == PKT_SECRET_KEY ? "sec" : "ssb",
-                     (node->flag & NODFLG_SELKEY) ? '*' : ' ',
-                      pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
-                     keystr (pk->keyid));
+
+          xfree (serialno);
+          serialno = NULL;
+          {
+            char *hexgrip;
+
+            err = hexkeygrip_from_pk (pk, &hexgrip);
+            if (err)
+              {
+                log_error ("error computing a keygrip: %s\n",
+                           gpg_strerror (err));
+                have_seckey = 0;
+              }
+            else
+              have_seckey = !agent_get_keyinfo (ctrl, hexgrip, &serialno);
+            xfree (hexgrip);
+          }
+
+         tty_fprintf
+            (fp, "%s%c %s/%s",
+             node->pkt->pkttype == PKT_PUBLIC_KEY && have_seckey? "sec" :
+             node->pkt->pkttype == PKT_PUBLIC_KEY ?               "pub" :
+             have_seckey ?                                        "ssb" :
+                                                                  "sub",
+             (node->flag & NODFLG_SELKEY) ? '*' : ' ',
+             pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
+             keystr (pk->keyid));
 
           if (opt.legacy_list_mode)
             tty_fprintf (fp, "  ");
@@ -3061,10 +3086,30 @@ show_key_with_all_names (estream_t fp,
          tty_fprintf (fp, _("usage: %s"), usagestr_from_pk (pk, 1));
          tty_fprintf (fp, "\n");
 
-         if (pk->seckey_info
+          if (serialno)
+            {
+              /* The agent told us that a secret key is available and
+                 that it has been stored on a card.  */
+             tty_fprintf (fp, "%*s%s", opt.legacy_list_mode? 21:5, "",
+                           _("card-no: "));
+              if (strlen (serialno) == 32
+                  && !strncmp (serialno, "D27600012401", 12))
+                {
+                  /* This is an OpenPGP card.  Print the relevant part.  */
+                  /* Example: D2760001240101010001000003470000 */
+                  /*                          xxxxyyyyyyyy     */
+                  tty_fprintf (fp, "%.*s %.*s\n",
+                               4, serialno+16, 8, serialno+20);
+                }
+              else
+                tty_fprintf (fp, "%s\n", serialno);
+
+            }
+         else if (pk->seckey_info
               && pk->seckey_info->is_protected
               && pk->seckey_info->s2k.mode == 1002)
            {
+              /* FIXME: Check wether this code path is still used.  */
              tty_fprintf (fp, "%*s%s", opt.legacy_list_mode? 21:5, "",
                            _("card-no: "));
              if (pk->seckey_info->ivlen == 16
@@ -3136,13 +3181,17 @@ show_key_with_all_names (estream_t fp,
     tty_fprintf (fp, _("Please note that the shown key validity"
                        " is not necessarily correct\n"
                        "unless you restart the program.\n"));
+
+  xfree (serialno);
 }
 
 
 /* Display basic key information.  This function is suitable to show
    information on the key without any dependencies on the trustdb or
    any other internal GnuPG stuff.  KEYBLOCK may either be a public or
-   a secret key.*/
+   a secret key.  This function may be called with KEYBLOCK containing
+   secret keys and thus the printing of "pub" vs. "sec" does only
+   depend on the packet type and not by checking with gpg-agent.  */
 void
 show_basic_key_info (KBNODE keyblock)
 {
@@ -3194,10 +3243,11 @@ show_basic_key_info (KBNODE keyblock)
     }
 }
 
+
 static void
-show_key_and_fingerprint (KBNODE keyblock)
+show_key_and_fingerprint (kbnode_t keyblock, int with_subkeys)
 {
-  KBNODE node;
+  kbnode_t node;
   PKT_public_key *pk = NULL;
   char pkstrbuf[PUBKEY_STRING_SIZE];
 
@@ -3221,6 +3271,56 @@ show_key_and_fingerprint (KBNODE keyblock)
   tty_printf ("\n");
   if (pk)
     print_fingerprint (NULL, pk, 2);
+  if (with_subkeys)
+    {
+      for (node = keyblock; node; node = node->next)
+        {
+          if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+            {
+              pk = node->pkt->pkt.public_key;
+              tty_printf ("sub   %s/%s %s [%s]\n",
+                          pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
+                          keystr_from_pk(pk),
+                          datestr_from_pk (pk),
+                          usagestr_from_pk (pk, 0));
+
+              print_fingerprint (NULL, pk, 4);
+            }
+        }
+    }
+}
+
+
+/* Show a listing of the primary and its subkeys along with their
+   keygrips.  */
+static void
+show_key_and_grip (kbnode_t keyblock)
+{
+  kbnode_t node;
+  PKT_public_key *pk = NULL;
+  char pkstrbuf[PUBKEY_STRING_SIZE];
+  char *hexgrip;
+
+  for (node = keyblock; node; node = node->next)
+    {
+      if (node->pkt->pkttype == PKT_PUBLIC_KEY
+          || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+        {
+          pk = node->pkt->pkt.public_key;
+          tty_printf ("%s   %s/%s %s [%s]\n",
+                      node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
+                      pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
+                      keystr_from_pk(pk),
+                      datestr_from_pk (pk),
+                      usagestr_from_pk (pk, 0));
+
+          if (!hexkeygrip_from_pk (pk, &hexgrip))
+            {
+              tty_printf ("      Keygrip: %s\n", hexgrip);
+              xfree (hexgrip);
+            }
+        }
+    }
 }
 
 
index 796d18f..f03c148 100644 (file)
@@ -1520,6 +1520,13 @@ gen_ecc (int algo, const char *curve, kbnode_t pub_root,
        (((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY)
          && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))?
         " transient-key" : ""));
+  else if (algo == PUBKEY_ALGO_ECDH && !strcmp (curve, "Curve25519"))
+    keyparms = xtryasprintf
+      ("(genkey(ecc(curve %zu:%s)(flags djb-tweak comp%s)))",
+       strlen (curve), curve,
+       (((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY)
+         && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))?
+        " transient-key" : ""));
   else
     keyparms = xtryasprintf
       ("(genkey(ecc(curve %zu:%s)(flags nocomp%s)))",
@@ -2125,7 +2132,7 @@ ask_keysize (int algo, unsigned int primary_keysize)
    function may adjust.  Returns a malloced string with the name of
    the curve.  BOTH tells that gpg creates a primary and subkey. */
 static char *
-ask_curve (int *algo, int both)
+ask_curve (int *algo, int *subkey_algo)
 {
   struct {
     const char *name;
@@ -2176,7 +2183,7 @@ ask_curve (int *algo, int both)
         continue;
       if (!gcry_pk_get_curve (keyparms, 0, NULL))
         continue;
-      if (both && curves[idx].fix_curve)
+      if (subkey_algo && curves[idx].fix_curve)
         {
           /* Both Curve 25519 keys are to be created.  Check that
              Libgcrypt also supports the real Curve25519.  */
@@ -2241,6 +2248,11 @@ ask_curve (int *algo, int both)
           if ((*algo == PUBKEY_ALGO_ECDSA || *algo == PUBKEY_ALGO_EDDSA)
               && curves[idx].fix_curve)
             {
+              if (subkey_algo && *subkey_algo == PUBKEY_ALGO_ECDSA)
+                {
+                  *subkey_algo = PUBKEY_ALGO_EDDSA;
+                  result = xstrdup ("Ed25519");
+                }
               *algo = PUBKEY_ALGO_EDDSA;
               result = xstrdup ("Ed25519");
             }
@@ -3672,7 +3684,7 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
               || algo == PUBKEY_ALGO_EDDSA
               || algo == PUBKEY_ALGO_ECDH)
             {
-              curve = ask_curve (&algo, both);
+              curve = ask_curve (&algo, &subkey_algo);
               r = xmalloc_clear( sizeof *r + 20 );
               r->key = pKEYTYPE;
               sprintf( r->u.value, "%d", algo);
@@ -3743,7 +3755,7 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
               || algo == PUBKEY_ALGO_EDDSA
               || algo == PUBKEY_ALGO_ECDH)
             {
-              curve = ask_curve (&algo, 0);
+              curve = ask_curve (&algo, NULL);
               nbits = 0;
               r = xmalloc_clear (sizeof *r + strlen (curve));
               r->key = pKEYCURVE;
@@ -4292,7 +4304,7 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock)
   else if (algo == PUBKEY_ALGO_ECDSA
            || algo == PUBKEY_ALGO_EDDSA
            || algo == PUBKEY_ALGO_ECDH)
-    curve = ask_curve (&algo, 0);
+    curve = ask_curve (&algo, NULL);
   else
     nbits = ask_keysize (algo, 0);
 
index 90d982e..42a5f9f 100644 (file)
@@ -119,9 +119,9 @@ pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize)
   else if (prefix)
     {
       char *curve = openpgp_oid_to_str (pk->pkey[0]);
-      const char *name = openpgp_oid_to_curve (curve);
+      const char *name = openpgp_oid_to_curve (curve, 0);
 
-      if (*name && *name != '?')
+      if (name)
         snprintf (buffer, bufsize, "%s", name);
       else if (curve)
         snprintf (buffer, bufsize, "E_%s", curve);
@@ -766,9 +766,12 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
         else
           {
             err = gcry_sexp_build (&s_pkey, NULL,
-                                   pk->pubkey_algo == PUBKEY_ALGO_EDDSA ?
-                                   "(public-key(ecc(curve%s)(flags eddsa)(q%m)))"
-                                   : "(public-key(ecc(curve%s)(q%m)))",
+                                   pk->pubkey_algo == PUBKEY_ALGO_EDDSA?
+                                   "(public-key(ecc(curve%s)(flags eddsa)(q%m)))":
+                                   (pk->pubkey_algo == PUBKEY_ALGO_ECDH
+                                    && openpgp_oid_is_crv25519 (pk->pkey[0]))?
+                                   "(public-key(ecc(curve%s)(flags djb-tweak)(q%m)))":
+                                   "(public-key(ecc(curve%s)(q%m)))",
                                    curve, pk->pkey[1]);
             xfree (curve);
           }
index d4e572e..0383931 100644 (file)
@@ -1031,7 +1031,7 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr,
 
              validity = uid_trust_string_fixed (pk, uid);
              indent =
-               (keystrlen () + 9) -
+               (keystrlen () + (opt.legacy_list_mode? 9:11)) -
                atoi (uid_trust_string_fixed (NULL, NULL));
 
              if (indent < 0 || indent > 40)
@@ -1040,7 +1040,8 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr,
              es_fprintf (es_stdout, "uid%*s%s ", indent, "", validity);
            }
          else
-           es_fprintf (es_stdout, "uid%*s", (int) keystrlen () + 10, "");
+           es_fprintf (es_stdout, "uid%*s",
+                        (int) keystrlen () + (opt.legacy_list_mode? 10:12), "");
 
          print_utf8_buffer (es_stdout, uid->name, uid->len);
          es_putc ('\n', es_stdout);
@@ -1086,18 +1087,6 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr,
                   pubkey_string (pk2, pkstrbuf, sizeof pkstrbuf),
                  keystr_from_pk (pk2), datestr_from_pk (pk2));
 
-          if (pk2->pubkey_algo == PUBKEY_ALGO_ECDSA
-              || pk2->pubkey_algo == PUBKEY_ALGO_EDDSA
-              || pk2->pubkey_algo == PUBKEY_ALGO_ECDH)
-            {
-              char *curve = openpgp_oid_to_str (pk2->pkey[0]);
-              const char *name = openpgp_oid_to_curve (curve);
-              if (!*name || *name == '?')
-                name = curve;
-              es_fprintf (es_stdout, " %s", name);
-              xfree (curve);
-            }
-
           if ((opt.list_options & LIST_SHOW_USAGE))
             {
               es_fprintf (es_stdout, " [%s]", usagestr_from_pk (pk2, 0));
@@ -1358,8 +1347,8 @@ list_keyblock_colon (KBNODE keyblock, int secret, int has_secret, int fpr)
       || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
     {
       char *curve = openpgp_oid_to_str (pk->pkey[0]);
-      const char *name = openpgp_oid_to_curve (curve);
-      if (!*name || *name == '?')
+      const char *name = openpgp_oid_to_curve (curve, 0);
+      if (!name)
         name = curve;
       es_fputs (name, es_stdout);
       xfree (curve);
@@ -1487,8 +1476,8 @@ list_keyblock_colon (KBNODE keyblock, int secret, int has_secret, int fpr)
               || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
             {
               char *curve = openpgp_oid_to_str (pk->pkey[0]);
-              const char *name = openpgp_oid_to_curve (curve);
-              if (!*name || *name == '?')
+              const char *name = openpgp_oid_to_curve (curve, 0);
+              if (!name)
                 name = curve;
               es_fputs (name, es_stdout);
               xfree (curve);
@@ -1725,6 +1714,7 @@ print_icao_hexdigit (estream_t fp, int c)
  *      1: print using log_info ()
  *      2: direct use of tty
  *      3: direct use of tty but only primary key.
+ *      4: direct use of tty but only subkey.
  *     10: Same as 0 but with_colons etc is ignored.
  *
  * Modes 1 and 2 will try and print both subkey and primary key
@@ -1783,7 +1773,7 @@ print_fingerprint (estream_t override_fp, PKT_public_key *pk, int mode)
     {
       fp = override_fp; /* Use tty or given stream.  */
       if (primary)
-       /* TRANSLATORS: this should fit into 24 bytes to that the
+       /* TRANSLATORS: this should fit into 24 bytes so that the
         * fingerprint data is properly aligned with the user ID */
        text = _(" Primary key fingerprint:");
       else
@@ -1794,6 +1784,11 @@ print_fingerprint (estream_t override_fp, PKT_public_key *pk, int mode)
       fp = override_fp; /* Use tty or given stream.  */
       text = _("      Key fingerprint =");
     }
+  else if (mode == 4)
+    {
+      fp = override_fp; /* Use tty or given stream.  */
+      text = _("      Subkey fingerprint:");
+    }
   else
     {
       fp = override_fp? override_fp : es_stdout;
index f4bf17f..06c497d 100644 (file)
@@ -182,7 +182,7 @@ void write_status_error (const char *where, gpg_error_t err);
 void write_status_errcode (const char *where, int errcode);
 void write_status_text ( int no, const char *text );
 void write_status_strings (int no, const char *text,
-                           ...) GNUPG_GCC_A_SENTINEL(0);
+                           ...) GPGRT_ATTR_SENTINEL(0);
 void write_status_buffer ( int no,
                            const char *buffer, size_t len, int wrap );
 void write_status_text_and_buffer ( int no, const char *text,
index c90b9e3..f7b7c6b 100644 (file)
@@ -1031,7 +1031,9 @@ list_node (CTX c, kbnode_t node)
                     es_printf ("%s:::::::::",
                                node->pkt->pkt.user_id->attrib_data?"uat":"uid");
                   else
-                    es_printf ("uid%*s", 28, "" );
+                    es_printf ("uid%*s",
+                               (int)keystrlen ()+(opt.legacy_list_mode? 9:11),
+                               "" );
                   print_userid (node->pkt);
                   if (opt.with_colons)
                     es_putc (':', es_stdout);
index 5116404..478612a 100644 (file)
@@ -2086,8 +2086,8 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
                    || algorithm == PUBKEY_ALGO_ECDH) && i==0)
                 {
                   char *curve = openpgp_oid_to_str (pk->pkey[0]);
-                  es_fprintf (listfp, " %s (%s)",
-                              openpgp_oid_to_curve (curve), curve);
+                  const char *name = openpgp_oid_to_curve (curve, 0);
+                  es_fprintf (listfp, " %s (%s)", name?name:"", curve);
                   xfree (curve);
                 }
               es_putc ('\n', listfp);
index d72275b..a834621 100644 (file)
@@ -228,9 +228,13 @@ pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data,
             rc = gpg_error_from_syserror ();
           else
             {
+              int with_djb_tweak_flag = openpgp_oid_is_crv25519 (pkey[0]);
+
               /* Now use the ephemeral secret to compute the shared point.  */
               rc = gcry_sexp_build (&s_pkey, NULL,
-                                    "(public-key(ecdh(curve%s)(q%m)))",
+                                    with_djb_tweak_flag ?
+                                    "(public-key(ecdh(curve%s)(flags djb-tweak)(q%m)))"
+                                    : "(public-key(ecdh(curve%s)(q%m)))",
                                     curve, pkey[1]);
               xfree (curve);
               /* Put K into a simplified S-expression.  */
index cb834af..fd7f812 100644 (file)
@@ -250,8 +250,8 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
       if(err)
         goto leave;
 
-      /* Reuse NFRAME, which size is sufficient to include the session key.  */
-      err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &nframe, decoded);
+      xfree (frame);
+      err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &frame, &nframe, decoded);
       mpi_release (decoded);
       if (err)
         goto leave;
index 371833d..c766813 100644 (file)
--- a/g13/g13.h
+++ b/g13/g13.h
@@ -106,7 +106,7 @@ void g13_exit (int rc);
 void g13_init_default_ctrl (struct server_control_s *ctrl);
 
 /*-- server.c (commonly used, thus declared here) --*/
-gpg_error_t g13_status (ctrl_t ctrl, int no, ...) GNUPG_GCC_A_SENTINEL(0);
+gpg_error_t g13_status (ctrl_t ctrl, int no, ...) GPGRT_ATTR_SENTINEL(0);
 
 
 #endif /*G13_H*/
index e6b7a4d..1d0417a 100644 (file)
--- a/po/ca.po
+++ b/po/ca.po
@@ -3217,6 +3217,10 @@ msgstr "desa i ix"
 msgid "show key fingerprint"
 msgstr "mostra empremta"
 
+#, fuzzy
+msgid "show the keygrip"
+msgstr "Notació de signatura: "
+
 msgid "list key and user IDs"
 msgstr "llista claus i ID"
 
@@ -3296,10 +3300,6 @@ msgstr "No podeu canviar la data de caducitat de les claus v3\n"
 msgid "flag the selected user ID as primary"
 msgstr "marca l'ID d'usuari com a primari"
 
-#, fuzzy
-msgid "toggle between the secret and public key listings"
-msgstr "canvia entre el llistat de claus secretes i públiques"
-
 msgid "list preferences (expert)"
 msgstr "llista les preferències (expert)"
 
@@ -3364,9 +3364,6 @@ msgstr "La clau secreta està disponible.\n"
 msgid "Need the secret key to do this.\n"
 msgstr "Cal la clau secreta per a fer açò.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Useu l'ordre «toggle» abans.\n"
-
 msgid ""
 "* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
@@ -4390,7 +4387,7 @@ msgstr "Empremtes digital de la clau primària:"
 msgid "     Subkey fingerprint:"
 msgstr "     Empremta digital de la subclau:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr " Empremta digital de la clau primària:"
@@ -8533,6 +8530,13 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "canvia entre el llistat de claus secretes i públiques"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Useu l'ordre «toggle» abans.\n"
+
+#, fuzzy
 #~ msgid "Passphrase"
 #~ msgstr "la contrasenya és errònia"
 
index 00a8c34..ff197ba 100644 (file)
--- a/po/cs.po
+++ b/po/cs.po
@@ -2991,6 +2991,11 @@ msgstr "uložit a ukončit"
 msgid "show key fingerprint"
 msgstr "vypsat otisk klíče"
 
+#, fuzzy
+#| msgid "Enter the keygrip: "
+msgid "show the keygrip"
+msgstr "Vložte keygrip: "
+
 msgid "list key and user IDs"
 msgstr "vypsat seznam klíčů a id uživatelů"
 
@@ -3051,9 +3056,6 @@ msgstr "změnit datum expirace pro klíč nebo vybrané podklíče"
 msgid "flag the selected user ID as primary"
 msgstr "označit vybrané uživatelské ID jako primární"
 
-msgid "toggle between the secret and public key listings"
-msgstr "přepnout mezi výpisem seznamu tajných a veřejných klíčů"
-
 msgid "list preferences (expert)"
 msgstr "vypsat seznam předvoleb (pro experty)"
 
@@ -3106,9 +3108,6 @@ msgstr "Tajný klíč je dostupný.\n"
 msgid "Need the secret key to do this.\n"
 msgstr "Pro provedení této operace je potřeba tajný klíč.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Prosím, nejdříve použijte příkaz „toggle“ (přepnout).\n"
-
 msgid ""
 "* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
@@ -4057,7 +4056,7 @@ msgstr "Otisk primárního klíče:"
 msgid "     Subkey fingerprint:"
 msgstr "         Otisk podklíče:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr "  Otisk primárního klíče:"
@@ -7967,6 +7966,12 @@ msgstr ""
 "Syntaxe: gpg-check-pattern [volby] soubor_se_vzorem\n"
 "Prověří heslo zadané na vstupu proti souboru se vzory\n"
 
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "přepnout mezi výpisem seznamu tajných a veřejných klíčů"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Prosím, nejdříve použijte příkaz „toggle“ (přepnout).\n"
+
 #~ msgid "Passphrase"
 #~ msgstr "Heslo"
 
index e9b5f90..01700f0 100644 (file)
--- a/po/da.po
+++ b/po/da.po
@@ -3133,6 +3133,14 @@ msgstr "gem og afslut"
 msgid "show key fingerprint"
 msgstr "vis nøglefingeraftryk"
 
+# key grip
+# chiefly  ( US ) See also grip the person in charge of moving and setting up camera
+# tracks and scenery in a film or television studio
+#, fuzzy
+#| msgid "Enter the keygrip: "
+msgid "show the keygrip"
+msgstr "Indtst nøglegrebet: "
+
 msgid "list key and user IDs"
 msgstr "vis nøgle og bruger-id'er"
 
@@ -3194,9 +3202,6 @@ msgstr "ændr udløbsdatoen for nøglen eller valgte undernøgler"
 msgid "flag the selected user ID as primary"
 msgstr "marker den valgte bruger-id som primær"
 
-msgid "toggle between the secret and public key listings"
-msgstr "skift mellem hemmelig og offentlig nøglevisning"
-
 msgid "list preferences (expert)"
 msgstr "vis præferencer (ekspert)"
 
@@ -3250,9 +3255,6 @@ msgstr "Hemmelig nøgle er tilgængelig.\n"
 msgid "Need the secret key to do this.\n"
 msgstr "Har brug for den hemmelige nøgle for dette.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Brug venligst kommandoen »toggle« først.\n"
-
 #, fuzzy
 #| msgid ""
 #| "* The `sign' command may be prefixed with an `l' for local signatures "
@@ -4252,7 +4254,7 @@ msgstr "Primær nøglefingeraftryk:"
 msgid "     Subkey fingerprint:"
 msgstr "     Undernøglefingeraftryk:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr "Primær nøglefingeraftryk:"
@@ -8510,6 +8512,12 @@ msgstr ""
 "Syntaks: gpg-check-pattern [tilvalg] mønsterfil\n"
 "Kontroller en adgangsfrase angivet på stdin mod mønsterfilen\n"
 
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "skift mellem hemmelig og offentlig nøglevisning"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Brug venligst kommandoen »toggle« først.\n"
+
 #~ msgid "Passphrase"
 #~ msgstr "Adgangsfrase"
 
index 96dfa65..368fce9 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: 2015-07-01 13:04+0200\n"
+"PO-Revision-Date: 2015-08-11 13:52+0200\n"
 "Last-Translator: Werner Koch <wk@gnupg.org>\n"
 "Language-Team: German <de@li.org>\n"
 "Language: de\n"
@@ -2994,6 +2994,9 @@ msgstr "speichern und Menü verlassen"
 msgid "show key fingerprint"
 msgstr "Fingerabdruck des Schlüssels anzeigen"
 
+msgid "show the keygrip"
+msgstr "\"Keygrip\" des Schlüssels anzeigen"
+
 msgid "list key and user IDs"
 msgstr "Schlüssel und User-IDs auflisten"
 
@@ -3055,9 +3058,6 @@ msgstr ""
 msgid "flag the selected user ID as primary"
 msgstr "User-ID als Haupt-User-ID kennzeichnen"
 
-msgid "toggle between the secret and public key listings"
-msgstr "Umschalten zwischen dem Auflisten geheimer und öffentlicher Schlüssel"
-
 msgid "list preferences (expert)"
 msgstr "Liste der Voreinstellungen (für Experten)"
 
@@ -3114,9 +3114,6 @@ msgstr "Geheimer Schlüssel ist vorhanden.\n"
 msgid "Need the secret key to do this.\n"
 msgstr "Hierzu wird der geheime Schlüssel benötigt.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Bitte verwenden sie zunächst den Befehl \"toggle\"\n"
-
 msgid ""
 "* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
@@ -4077,7 +4074,7 @@ msgstr "Haupt-Fingerabdruck  ="
 msgid "     Subkey fingerprint:"
 msgstr "Unter-Fingerabdruck  ="
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr " Haupt-Fingerabdruck  ="
@@ -8090,6 +8087,13 @@ msgstr ""
 "Syntax: gpg-check-pattern [optionen] Musterdatei\n"
 "Die von stdin gelesene Passphrase gegen die Musterdatei prüfen\n"
 
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr ""
+#~ "Umschalten zwischen dem Auflisten geheimer und öffentlicher Schlüssel"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Bitte verwenden sie zunächst den Befehl \"toggle\"\n"
+
 #~ msgid "Passphrase"
 #~ msgstr "Passphrase"
 
index 18bb364..9cbcf5f 100644 (file)
--- a/po/el.po
+++ b/po/el.po
@@ -3135,6 +3135,10 @@ msgstr "
 msgid "show key fingerprint"
 msgstr "áðåéêüíéóç ôïõ fingerprint"
 
+#, fuzzy
+msgid "show the keygrip"
+msgstr "Óçìåßùóç õðïãñáöÞò: "
+
 msgid "list key and user IDs"
 msgstr "áðåéêüíéóç ôùí êëåéäéþí êáé ôùí user ID"
 
@@ -3206,10 +3210,6 @@ msgstr "
 msgid "flag the selected user ID as primary"
 msgstr "óçìåßùóç ôïõ user ID óáí ðñùôåýùí"
 
-#, fuzzy
-msgid "toggle between the secret and public key listings"
-msgstr "áëëáãÞ ìåôáîý ôçò áðåéêüíéóçò ìõóôéêïý êáé äçìüóéïõ êëåéäéïý"
-
 msgid "list preferences (expert)"
 msgstr "áðåéêüíéóç ðñïåðéëïãþí (åéäéêÝò)"
 
@@ -3272,9 +3272,6 @@ msgstr "
 msgid "Need the secret key to do this.\n"
 msgstr "Áðáéôåßôáé ôï ìõóôéêü êëåéäß ãéá íá ãßíåé áõôü.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Ðáñáêáëþ ÷ñçóéìïðïéåßóôå ôçí åíôïëÞ \"toggle\" ðñþôá.\n"
-
 msgid ""
 "* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
@@ -4287,7 +4284,7 @@ msgstr "
 msgid "     Subkey fingerprint:"
 msgstr "     Áðïôýðùìá õðïêëåéäéïý:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr " Áðïôýðùìá ðñùôåýùí êëåéäéïý:"
@@ -8354,6 +8351,13 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "áëëáãÞ ìåôáîý ôçò áðåéêüíéóçò ìõóôéêïý êáé äçìüóéïõ êëåéäéïý"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Ðáñáêáëþ ÷ñçóéìïðïéåßóôå ôçí åíôïëÞ \"toggle\" ðñþôá.\n"
+
+#, fuzzy
 #~ msgid "Passphrase"
 #~ msgstr "êáêÞ öñÜóç êëåéäß"
 
index 7181f63..062b2f0 100644 (file)
--- a/po/eo.po
+++ b/po/eo.po
@@ -3128,6 +3128,10 @@ msgstr "skribi kaj fini"
 msgid "show key fingerprint"
 msgstr "montri fingrospuron"
 
+#, fuzzy
+msgid "show the keygrip"
+msgstr "Subskribo-notacio: "
+
 msgid "list key and user IDs"
 msgstr "listigi þlosilojn kaj uzantidentigilojn"
 
@@ -3199,10 +3203,6 @@ msgstr "Vi ne povas 
 msgid "flag the selected user ID as primary"
 msgstr "marku uzantidentigilon kiel æefan"
 
-#, fuzzy
-msgid "toggle between the secret and public key listings"
-msgstr "de sekreta aý publika listo iri al la alia"
-
 msgid "list preferences (expert)"
 msgstr "listigi preferojn (spertula)"
 
@@ -3263,9 +3263,6 @@ msgstr "Sekreta 
 msgid "Need the secret key to do this.\n"
 msgstr "Bezonas la sekretan þlosilon por fari tion.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Bonvolu uzi la komandon \"toggle\" unue.\n"
-
 msgid ""
 "* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
@@ -4268,7 +4265,7 @@ msgstr "listigi 
 msgid "     Subkey fingerprint:"
 msgstr "     Þlosilo-fingrospuro ="
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 #, fuzzy
 msgid " Primary key fingerprint:"
@@ -8307,6 +8304,13 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "de sekreta aý publika listo iri al la alia"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Bonvolu uzi la komandon \"toggle\" unue.\n"
+
+#, fuzzy
 #~ msgid "Passphrase"
 #~ msgstr "malbona pasfrazo"
 
index 8cd141b..40ebb72 100644 (file)
--- a/po/es.po
+++ b/po/es.po
@@ -3153,6 +3153,11 @@ msgstr "graba y sale"
 msgid "show key fingerprint"
 msgstr "muestra huella dactilar de la clave"
 
+#, fuzzy
+#| msgid "Enter the keygrip: "
+msgid "show the keygrip"
+msgstr "Introduzca keygrip: "
+
 msgid "list key and user IDs"
 msgstr "lista clave e identificadores de usuario"
 
@@ -3213,9 +3218,6 @@ msgstr "cambiar la fecha de caducidad para la clave o subclaves seleccionadas"
 msgid "flag the selected user ID as primary"
 msgstr "marcar ID de usuario seleccionado como primario"
 
-msgid "toggle between the secret and public key listings"
-msgstr "cambiar entre lista de claves secretas y públicas"
-
 msgid "list preferences (expert)"
 msgstr "mostrar preferencias (experto)"
 
@@ -3267,9 +3269,6 @@ msgstr "Clave secreta disponible.\n"
 msgid "Need the secret key to do this.\n"
 msgstr "Se necesita la clave secreta para hacer esto.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Por favor use la orden \"cambia\" primero.\n"
-
 #, fuzzy
 #| msgid ""
 #| "* The `sign' command may be prefixed with an `l' for local signatures "
@@ -4259,7 +4258,7 @@ msgstr "Huellas dactilares de la clave primaria:"
 msgid "     Subkey fingerprint:"
 msgstr "     Huella de subclave:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr " Huella clave primaria:"
@@ -8557,6 +8556,12 @@ msgstr ""
 "Compara frase contraseña dada en entrada estándar con un fichero de "
 "patrones\n"
 
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "cambiar entre lista de claves secretas y públicas"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Por favor use la orden \"cambia\" primero.\n"
+
 # ¿Por qué no frase de paso?
 # Porque todo el mundo sabe lo que es una contraseña
 # y una "frase de paso" no. Soy consciente de que se
index 4066f58..5ec88c9 100644 (file)
--- a/po/et.po
+++ b/po/et.po
@@ -3112,6 +3112,10 @@ msgstr "salvesta ja v
 msgid "show key fingerprint"
 msgstr "näita sõrmejälge"
 
+#, fuzzy
+msgid "show the keygrip"
+msgstr "Allkirja noteerimine: "
+
 msgid "list key and user IDs"
 msgstr "näita võtit ja kasutaja IDd"
 
@@ -3182,10 +3186,6 @@ msgstr "v3 v
 msgid "flag the selected user ID as primary"
 msgstr "märgi kasutaja ID primaarseks"
 
-#, fuzzy
-msgid "toggle between the secret and public key listings"
-msgstr "lülita salajaste või avalike võtmete loendi vahel"
-
 msgid "list preferences (expert)"
 msgstr "näita eelistusi (ekspert)"
 
@@ -3246,9 +3246,6 @@ msgstr "Salajane v
 msgid "Need the secret key to do this.\n"
 msgstr "Selle tegamiseks on vaja salajast võtit.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Palun kasutage kõigepealt käsku \"toggle\".\n"
-
 msgid ""
 "* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
@@ -4241,7 +4238,7 @@ msgstr "Primaarse v
 msgid "     Subkey fingerprint:"
 msgstr "    Alamvõtme sõrmejälg:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr " Primaarse võtme sõrmejälg:"
@@ -8278,6 +8275,13 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "lülita salajaste või avalike võtmete loendi vahel"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Palun kasutage kõigepealt käsku \"toggle\".\n"
+
+#, fuzzy
 #~ msgid "Passphrase"
 #~ msgstr "halb parool"
 
index 98624e2..14f4f16 100644 (file)
--- a/po/fi.po
+++ b/po/fi.po
@@ -3133,6 +3133,10 @@ msgstr "tallenna ja lopeta"
 msgid "show key fingerprint"
 msgstr "näytä sormenjälki"
 
+#, fuzzy
+msgid "show the keygrip"
+msgstr "Allekirjoitusnotaatio: "
+
 msgid "list key and user IDs"
 msgstr "näytä avaimet ja käyttäjätunnukset"
 
@@ -3203,10 +3207,6 @@ msgstr "Et voi muuttaa v3-avainten vanhentumispäivää\n"
 msgid "flag the selected user ID as primary"
 msgstr "merkitse käyttäjätunnus ensisijaiseksi"
 
-#, fuzzy
-msgid "toggle between the secret and public key listings"
-msgstr "vaihda salaisten ja julkisten avainten luettelon välillä"
-
 msgid "list preferences (expert)"
 msgstr "näytä valinnat (asiantuntija)"
 
@@ -3267,9 +3267,6 @@ msgstr "Salainen avain on saatavilla.\n"
 msgid "Need the secret key to do this.\n"
 msgstr "Tähän tarvitaan salainen avain.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Käytä ensin komentoa \"toggle\".\n"
-
 msgid ""
 "* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
@@ -4272,7 +4269,7 @@ msgstr "Ensisijaisen avaimen sormenjälki:"
 msgid "     Subkey fingerprint:"
 msgstr "     Aliavaimen sormenjälki:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr " Ensisijaisen avaimen sormenjälki:"
@@ -8337,6 +8334,13 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "vaihda salaisten ja julkisten avainten luettelon välillä"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Käytä ensin komentoa \"toggle\".\n"
+
+#, fuzzy
 #~ msgid "Passphrase"
 #~ msgstr "väärä salasana"
 
index 6ba3bd0..aed3bb7 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -3016,6 +3016,11 @@ msgstr "enregistrer et quitter"
 msgid "show key fingerprint"
 msgstr "afficher l'empreinte de la clef"
 
+#, fuzzy
+#| msgid "Enter the keygrip: "
+msgid "show the keygrip"
+msgstr "Entrez le keygrip : "
+
 msgid "list key and user IDs"
 msgstr "afficher la clef et les identités"
 
@@ -3079,10 +3084,6 @@ msgstr ""
 msgid "flag the selected user ID as primary"
 msgstr "marquer l'identité sélectionnée comme principale"
 
-msgid "toggle between the secret and public key listings"
-msgstr ""
-"passer de la liste de clefs secrètes à celle de clefs privées ou vice versa"
-
 msgid "list preferences (expert)"
 msgstr "afficher les préférences (expert)"
 
@@ -3138,9 +3139,6 @@ msgstr "La clef secrète est disponible.\n"
 msgid "Need the secret key to do this.\n"
 msgstr "La clef secrète est nécessaire pour faire cela.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Veuillez d'abord utiliser la commande « toggle ».\n"
-
 msgid ""
 "* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
@@ -4118,7 +4116,7 @@ msgstr "Empreinte de clef principale :"
 msgid "     Subkey fingerprint:"
 msgstr "   Empreinte de la sous-clef :"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr "Empreinte clef princip. :"
@@ -8201,6 +8199,14 @@ msgstr ""
 "Vérifier une phrase secrète donnée sur l'entrée standard par rapport à "
 "ficmotif\n"
 
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr ""
+#~ "passer de la liste de clefs secrètes à celle de clefs privées ou vice "
+#~ "versa"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Veuillez d'abord utiliser la commande « toggle ».\n"
+
 #~ msgid "Passphrase"
 #~ msgstr "Phrase secrète"
 
index 67a1cd6..ee50059 100644 (file)
--- a/po/gl.po
+++ b/po/gl.po
@@ -3130,6 +3130,10 @@ msgstr "gardar e sa
 msgid "show key fingerprint"
 msgstr "amosar fingerprint"
 
+#, fuzzy
+msgid "show the keygrip"
+msgstr "Notación de sinaturas: "
+
 msgid "list key and user IDs"
 msgstr "listar chave e IDs de usuario"
 
@@ -3202,10 +3206,6 @@ msgstr "Non pode cambia-la data de expiraci
 msgid "flag the selected user ID as primary"
 msgstr "marcar un ID de usuario coma primario"
 
-#, fuzzy
-msgid "toggle between the secret and public key listings"
-msgstr "cambiar entre o listado de chaves públicas e secretas"
-
 msgid "list preferences (expert)"
 msgstr "lista-las preferencias (expertos)"
 
@@ -3270,9 +3270,6 @@ msgstr "A chave secreta est
 msgid "Need the secret key to do this.\n"
 msgstr "Cómpre a chave secreta para facer isto.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Por favor, empregue o comando \"toggle\" antes.\n"
-
 msgid ""
 "* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
@@ -4286,7 +4283,7 @@ msgstr "Pegada dactilar da chave primaria:"
 msgid "     Subkey fingerprint:"
 msgstr "     Pegada dactilar da sub-chave:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr "Pegada dactilar da chave primaria:"
@@ -8362,6 +8359,13 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "cambiar entre o listado de chaves públicas e secretas"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Por favor, empregue o comando \"toggle\" antes.\n"
+
+#, fuzzy
 #~ msgid "Passphrase"
 #~ msgstr "contrasinal erróneo"
 
index d9ca173..df78cee 100644 (file)
--- a/po/hu.po
+++ b/po/hu.po
@@ -3111,6 +3111,10 @@ msgstr "ment
 msgid "show key fingerprint"
 msgstr "megmutatja az ujjlenyomatot"
 
+#, fuzzy
+msgid "show the keygrip"
+msgstr "Aláírás-jelölés: "
+
 msgid "list key and user IDs"
 msgstr "kilistázza a kulcs- és felhasználóazonosítókat"
 
@@ -3181,10 +3185,6 @@ msgstr "Nem v
 msgid "flag the selected user ID as primary"
 msgstr "felhasználóazonosító megjelölése elsõdlegesként"
 
-#, fuzzy
-msgid "toggle between the secret and public key listings"
-msgstr "váltás a titkos és a nyilvános kulcs listázása között"
-
 msgid "list preferences (expert)"
 msgstr "preferenciák listázása (szakértõ)"
 
@@ -3245,9 +3245,6 @@ msgstr "Titkos kulcs rendelkez
 msgid "Need the secret key to do this.\n"
 msgstr "Ehhez szükség van a titkos kulcsra.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Kérem, használja elõbb a \"toggle\" parancsot!\n"
-
 msgid ""
 "* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
@@ -4252,7 +4249,7 @@ msgstr "Els
 msgid "     Subkey fingerprint:"
 msgstr "         Alkulcsujjlenyomat:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr "Elsõdlegeskulcs-ujjlenyomat:"
@@ -8310,6 +8307,13 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "váltás a titkos és a nyilvános kulcs listázása között"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Kérem, használja elõbb a \"toggle\" parancsot!\n"
+
+#, fuzzy
 #~ msgid "Passphrase"
 #~ msgstr "rossz jelszó"
 
index 0777e4e..8cffa15 100644 (file)
--- a/po/id.po
+++ b/po/id.po
@@ -3116,6 +3116,10 @@ msgstr "simpan dan berhenti"
 msgid "show key fingerprint"
 msgstr "tampilkan fingerprint"
 
+#, fuzzy
+msgid "show the keygrip"
+msgstr "Notasi signature: "
+
 msgid "list key and user IDs"
 msgstr "tampilkan kunci dan ID user"
 
@@ -3186,10 +3190,6 @@ msgstr "Anda tidak dapat merubah batas waktu kunci v3\n"
 msgid "flag the selected user ID as primary"
 msgstr "tandai ID user sebagai primer"
 
-#, fuzzy
-msgid "toggle between the secret and public key listings"
-msgstr "ubah tampilan kunci rahasia dan publik"
-
 msgid "list preferences (expert)"
 msgstr "tampilkan preferensi (ahli)"
 
@@ -3250,9 +3250,6 @@ msgstr "Kunci rahasia tersedia.\n"
 msgid "Need the secret key to do this.\n"
 msgstr "Perlu kunci rahasia untuk melakukan hal ini.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Silakan gunakan dulu perintah \"toogle\".\n"
-
 msgid ""
 "* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
@@ -4256,7 +4253,7 @@ msgstr "Fingerprint kunci primer:"
 msgid "     Subkey fingerprint:"
 msgstr "     Fingerprint subkunci ="
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr "     Fingerprint kunci primer ="
@@ -8299,6 +8296,13 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "ubah tampilan kunci rahasia dan publik"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Silakan gunakan dulu perintah \"toogle\".\n"
+
+#, fuzzy
 #~ msgid "Passphrase"
 #~ msgstr "passphrase yang buruk"
 
index 31d4295..0486c6c 100644 (file)
--- a/po/it.po
+++ b/po/it.po
@@ -3123,6 +3123,10 @@ msgstr "salva ed esci"
 msgid "show key fingerprint"
 msgstr "mostra le impronte digitali"
 
+#, fuzzy
+msgid "show the keygrip"
+msgstr "Annotazione della firma: "
+
 msgid "list key and user IDs"
 msgstr "elenca le chiavi e gli user ID"
 
@@ -3193,10 +3197,6 @@ msgstr "Non 
 msgid "flag the selected user ID as primary"
 msgstr "imposta l'user ID come primario"
 
-#, fuzzy
-msgid "toggle between the secret and public key listings"
-msgstr "cambia tra visualizzare la chiave segreta e la chiave pubblica"
-
 msgid "list preferences (expert)"
 msgstr "elenca le preferenze (per esperti)"
 
@@ -3257,9 +3257,6 @@ msgstr "
 msgid "Need the secret key to do this.\n"
 msgstr "Per fare questo serve la chiave segreta.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Per favore usa prima il comando \"toggle\".\n"
-
 msgid ""
 "* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
@@ -4272,7 +4269,7 @@ msgstr "Impronta digitale della chiave primaria:"
 msgid "     Subkey fingerprint:"
 msgstr "    Impronta digitale della subchiave:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr " Impronta digitale della chiave primaria:"
@@ -8340,6 +8337,13 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "cambia tra visualizzare la chiave segreta e la chiave pubblica"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Per favore usa prima il comando \"toggle\".\n"
+
+#, fuzzy
 #~ msgid "Passphrase"
 #~ msgstr "passphrase errata"
 
index 581b1b3..51a9d74 100644 (file)
--- a/po/ja.po
+++ b/po/ja.po
@@ -8,9 +8,9 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: gnupg 2.1.5\n"
+"Project-Id-Version: gnupg 2.1.6\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2015-06-16 12:46+0900\n"
+"PO-Revision-Date: 2015-07-02 12:21+0900\n"
 "Last-Translator: NIIBE Yutaka <gniibe@fsij.org>\n"
 "Language-Team: none\n"
 "Language: ja\n"
@@ -85,7 +85,7 @@ msgstr ""
 "るために使われます)"
 
 msgid "PIN:"
-msgstr ""
+msgstr "PIN:"
 
 msgid "Passphrase:"
 msgstr "パスフレーズ:"
@@ -275,8 +275,7 @@ msgid_plural ""
 "A passphrase should contain at least %u digits or%%0Aspecial characters."
 msgstr[0] "パスフレーズは最低でも%u文字の数字か特殊文字を含むべきです。"
 
-#, fuzzy, c-format
-#| msgid "A passphrase may not be a known term or match%%0Acertain pattern."
+#, c-format
 msgid "A passphrase may not be a known term or match%%0Acertain pattern."
 msgstr ""
 "パスフレーズには、よく知られている用語や特定のパターンにマッチするものは%%0A"
@@ -645,12 +644,11 @@ msgstr "パスフレーズを変更する"
 msgid "I'll change it later"
 msgstr "後で変更する"
 
-#, fuzzy, c-format
-#| msgid "Do you really want to delete the selected keys? (y/N) "
+#, c-format
 msgid ""
 "Do you really want to delete the key identified by keygrip%%0A  %s%%0A  %%C"
 "%%0A?"
-msgstr "選択した鍵を本当に削除しますか? (y/N) "
+msgstr "本当にこの鍵: keygrip%%0A  %s%%0A  %%C%%0Aを削除しますか?"
 
 msgid "Delete key"
 msgstr "鍵を削除する"
@@ -803,7 +801,7 @@ msgstr ""
 
 #, c-format
 msgid "unknown debug flag '%s' ignored\n"
-msgstr ""
+msgstr "未知のdebugフラグ'%s'は無視されました\n"
 
 #, c-format
 msgid "no running gpg-agent - starting '%s'\n"
@@ -2896,6 +2894,11 @@ msgstr "保存して終了"
 msgid "show key fingerprint"
 msgstr "鍵のフィンガープリントを表示"
 
+#, fuzzy
+#| msgid "Enter the keygrip: "
+msgid "show the keygrip"
+msgstr "keygripを入力: "
+
 msgid "list key and user IDs"
 msgstr "鍵とユーザIDの一覧"
 
@@ -2956,9 +2959,6 @@ msgstr "鍵または選択した副鍵の有効期限を変更する"
 msgid "flag the selected user ID as primary"
 msgstr "選択したユーザIDを主にする"
 
-msgid "toggle between the secret and public key listings"
-msgstr "秘密鍵と公開鍵の一覧の反転"
-
 msgid "list preferences (expert)"
 msgstr "優先指定の一覧 (エキスパート)"
 
@@ -3010,9 +3010,6 @@ msgstr "秘密鍵が使用できます。\n"
 msgid "Need the secret key to do this.\n"
 msgstr "この実行には秘密鍵がいります。\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "まず\"toggle\"コマンドを使ってください。\n"
-
 msgid ""
 "* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
@@ -3930,15 +3927,12 @@ msgstr "クリティカルな署名注釈: "
 msgid "Signature notation: "
 msgstr "署名注釈: "
 
-#, fuzzy
-#| msgid "1 bad signature\n"
 msgid "1 good signature\n"
-msgstr "不正な署名1個\n"
+msgstr "正しい署名1個\n"
 
-#, fuzzy, c-format
-#| msgid "%d bad signatures\n"
+#, c-format
 msgid "%d good signatures\n"
-msgstr "不正な署名%d個\n"
+msgstr "正しい署名%d個\n"
 
 #, c-format
 msgid "Warning: %lu key(s) skipped due to their large size\n"
@@ -3953,7 +3947,7 @@ msgstr "主鍵のフィンガープリント:"
 msgid "     Subkey fingerprint:"
 msgstr "副鍵のフィンガープリント:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr "主鍵のフィンガープリント:"
@@ -7815,6 +7809,12 @@ msgstr ""
 "形式: gpg-check-pattern [オプション] パターンファイル\n"
 "パターンファイルに対して標準入力のパスフレーズを確認する\n"
 
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "秘密鍵と公開鍵の一覧の反転"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "まず\"toggle\"コマンドを使ってください。\n"
+
 #~ msgid "Passphrase"
 #~ msgstr "パスフレーズ"
 
index d85db65..c50c8d3 100644 (file)
--- a/po/nb.po
+++ b/po/nb.po
@@ -3065,6 +3065,11 @@ msgstr "lagre og avslutte"
 msgid "show key fingerprint"
 msgstr "vise nøkkelens fingeravtrykk"
 
+#, fuzzy
+#| msgid "show this help"
+msgid "show the keygrip"
+msgstr "vise denne hjelpen"
+
 msgid "list key and user IDs"
 msgstr "liste nøkler og brukerider"
 
@@ -3125,9 +3130,6 @@ msgstr ""
 msgid "flag the selected user ID as primary"
 msgstr "markere den valgte brukeriden som den primære"
 
-msgid "toggle between the secret and public key listings"
-msgstr "veksle mellom hemmelig og offentlig nøkkellisting"
-
 msgid "list preferences (expert)"
 msgstr "liste preferanser (ekspert)"
 
@@ -3179,9 +3181,6 @@ msgstr "Hemmelig n
 msgid "Need the secret key to do this.\n"
 msgstr "Trenger den hemmelige nøkkelen for å gjøre dette.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Vennligst bruk kommandoen «toggle» først.\n"
-
 msgid ""
 "* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
@@ -4147,7 +4146,7 @@ msgstr "Fingeravtrykk for prim
 msgid "     Subkey fingerprint:"
 msgstr "     Fingeravtrykk for undernøkkel:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr " Fingeravtrykk for primærnøkkel:"
@@ -8160,6 +8159,12 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "veksle mellom hemmelig og offentlig nøkkellisting"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Vennligst bruk kommandoen «toggle» først.\n"
+
 #, fuzzy
 #~ msgid "Passphrase"
 #~ msgstr "ugyldig passfrase"
index 9d70c8d..4f5d4a8 100644 (file)
--- a/po/pl.po
+++ b/po/pl.po
@@ -3138,6 +3138,11 @@ msgstr "zapis zmian i wyj
 msgid "show key fingerprint"
 msgstr "okazanie odcisku klucza"
 
+#, fuzzy
+#| msgid "Enter the keygrip: "
+msgid "show the keygrip"
+msgstr "Uchwyt klucza: "
+
 msgid "list key and user IDs"
 msgstr "lista kluczy i identyfikatorów u¿ytkownika"
 
@@ -3204,9 +3209,6 @@ msgstr "zmiana daty wyga
 msgid "flag the selected user ID as primary"
 msgstr "oznaczenie wybranego identyfikatora u¿ytkownika jako g³ównego"
 
-msgid "toggle between the secret and public key listings"
-msgstr "prze³±czenie pomiêdzy listami kluczy tajnych i publicznych"
-
 msgid "list preferences (expert)"
 msgstr "ustawienia (zaawansowane)"
 
@@ -3264,9 +3266,6 @@ msgstr "Dost
 msgid "Need the secret key to do this.\n"
 msgstr "Do wykonania tej operacji potrzebny jest klucz tajny.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Najpierw trzeba u¿yæ polecenia \"prze³\".\n"
-
 #, fuzzy
 #| msgid ""
 #| "* The `sign' command may be prefixed with an `l' for local signatures "
@@ -4274,7 +4273,7 @@ msgstr "Odcisk klucza g
 msgid "     Subkey fingerprint:"
 msgstr "      Odcisk podklucza:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr " Odcisk klucza g³ównego:"
@@ -8540,6 +8539,12 @@ 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 "toggle between the secret and public key listings"
+#~ msgstr "prze³±czenie pomiêdzy listami kluczy tajnych i publicznych"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Najpierw trzeba u¿yæ polecenia \"prze³\".\n"
+
 #~ msgid "Passphrase"
 #~ msgstr "Has³o"
 
index ef8fd0e..b9c0753 100644 (file)
--- a/po/pt.po
+++ b/po/pt.po
@@ -3121,6 +3121,10 @@ msgstr "gravar e sair"
 msgid "show key fingerprint"
 msgstr "mostra impressão digital"
 
+#, fuzzy
+msgid "show the keygrip"
+msgstr "Notação de assinatura: "
+
 msgid "list key and user IDs"
 msgstr "lista chave e identificadores de utilizadores"
 
@@ -3192,10 +3196,6 @@ msgstr "Voc
 msgid "flag the selected user ID as primary"
 msgstr "seleccionar o identificador do utilizador como primário"
 
-#, fuzzy
-msgid "toggle between the secret and public key listings"
-msgstr "alterna entre listagem de chave secreta e pública"
-
 msgid "list preferences (expert)"
 msgstr "lista preferências (perito)"
 
@@ -3258,9 +3258,6 @@ msgstr "Chave secreta dispon
 msgid "Need the secret key to do this.\n"
 msgstr "A chave secreta é necessária para fazer isto.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Por favor utilize o comando \"toggle\" primeiro.\n"
-
 msgid ""
 "* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
@@ -4264,7 +4261,7 @@ msgstr "Impress
 msgid "     Subkey fingerprint:"
 msgstr "      Impressão da subchave:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr "Impressão da chave primária:"
@@ -8316,6 +8313,13 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "alterna entre listagem de chave secreta e pública"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Por favor utilize o comando \"toggle\" primeiro.\n"
+
+#, fuzzy
 #~ msgid "Passphrase"
 #~ msgstr "frase secreta incorrecta"
 
index 753e4de..3cd7f33 100644 (file)
--- a/po/ro.po
+++ b/po/ro.po
@@ -3126,6 +3126,10 @@ msgstr "salveaz
 msgid "show key fingerprint"
 msgstr "afiºeazã amprenta cheii"
 
+#, fuzzy
+msgid "show the keygrip"
+msgstr "Notare semnãturã: "
+
 msgid "list key and user IDs"
 msgstr "enumerã chei ºi ID-uri utilizator"
 
@@ -3188,9 +3192,6 @@ msgstr "schimb
 msgid "flag the selected user ID as primary"
 msgstr "marcheazã ID-ul utilizator selectat ca primar"
 
-msgid "toggle between the secret and public key listings"
-msgstr "comutã între listele de chei secrete ºi publice"
-
 msgid "list preferences (expert)"
 msgstr "enumerã preferinþele (expert)"
 
@@ -3246,9 +3247,6 @@ msgstr "Cheia secret
 msgid "Need the secret key to do this.\n"
 msgstr "Aveþi nevoie de cheia secretã pentru a face aceasta.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Vã rugãm folosiþi mai întâi comanda \"toggle\".\n"
-
 #, fuzzy
 #| msgid ""
 #| "* The `sign' command may be prefixed with an `l' for local signatures "
@@ -4245,7 +4243,7 @@ msgstr "Amprent
 msgid "     Subkey fingerprint:"
 msgstr "     Amprentã subcheie:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr " Amprentã cheie primarã:"
@@ -8339,6 +8337,12 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "comutã între listele de chei secrete ºi publice"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Vã rugãm folosiþi mai întâi comanda \"toggle\".\n"
+
 #, fuzzy
 #~ msgid "Passphrase"
 #~ msgstr "frazã-parolã incorectã"
index 7633954..661299a 100644 (file)
--- a/po/ru.po
+++ b/po/ru.po
@@ -2932,6 +2932,11 @@ msgstr "сохранить и выйти"
 msgid "show key fingerprint"
 msgstr "показать отпечаток ключа"
 
+#, fuzzy
+#| msgid "Enter the keygrip: "
+msgid "show the keygrip"
+msgstr "Введите код ключа:"
+
 msgid "list key and user IDs"
 msgstr "вывести список ключей и ID пользователя"
 
@@ -2992,9 +2997,6 @@ msgstr "сменить срок действия ключа или выбран
 msgid "flag the selected user ID as primary"
 msgstr "пометить выбранный ID пользователя как первичный"
 
-msgid "toggle between the secret and public key listings"
-msgstr "переключение между просмотром открытых и закрытых ключей"
-
 msgid "list preferences (expert)"
 msgstr "список предпочтений (экспертам)"
 
@@ -3048,9 +3050,6 @@ msgstr "Закрытый ключ доступен.\n"
 msgid "Need the secret key to do this.\n"
 msgstr "Для данного действия нужен закрытый ключ.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Сначала воспользуйтесь командой \"toggle\".\n"
-
 msgid ""
 "* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
@@ -4001,7 +4000,7 @@ msgstr "Отпечаток главного ключа:"
 msgid "     Subkey fingerprint:"
 msgstr "      Отпечаток подключа:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr " Отпечаток главного ключа:"
@@ -7924,6 +7923,12 @@ msgstr ""
 "Синтаксис: gpg-check-pattern [параметры] файл_образцов\n"
 "Проверить фразу-пароль, поступающую из stdin, по файлу образцов\n"
 
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "переключение между просмотром открытых и закрытых ключей"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Сначала воспользуйтесь командой \"toggle\".\n"
+
 #~ msgid "Passphrase"
 #~ msgstr "Фраза-пароль"
 
index 9c1375d..562aeb7 100644 (file)
--- a/po/sk.po
+++ b/po/sk.po
@@ -3136,6 +3136,10 @@ msgstr "ulo
 msgid "show key fingerprint"
 msgstr "vypísa» fingerprint"
 
+#, fuzzy
+msgid "show the keygrip"
+msgstr "Podpisová notácia: "
+
 msgid "list key and user IDs"
 msgstr "vypísa» zoznam kµúèov a id u¾ívateµov"
 
@@ -3206,10 +3210,6 @@ msgstr "Nem
 msgid "flag the selected user ID as primary"
 msgstr "oznaèi» u¾ívateµské ID ako primárne"
 
-#, fuzzy
-msgid "toggle between the secret and public key listings"
-msgstr "prepnú» medzi vypísaním zoznamu tajných a verejných kµúèov"
-
 msgid "list preferences (expert)"
 msgstr "vypísa» zoznam predvolieb (pre expertov)"
 
@@ -3270,9 +3270,6 @@ msgstr "Tajn
 msgid "Need the secret key to do this.\n"
 msgstr "Na vykonanie tejto operácie je potrebný tajný kµúè.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Prosím, najskôr pou¾ite príkaz \"toggle\" (prepnú»).\n"
-
 msgid ""
 "* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
@@ -4269,7 +4266,7 @@ msgstr "Prim
 msgid "     Subkey fingerprint:"
 msgstr "     Fingerprint podkµúèa:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr " Primárny fingerprint kµúèa:"
@@ -8328,6 +8325,13 @@ msgid ""
 msgstr ""
 
 #, fuzzy
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "prepnú» medzi vypísaním zoznamu tajných a verejných kµúèov"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Prosím, najskôr pou¾ite príkaz \"toggle\" (prepnú»).\n"
+
+#, fuzzy
 #~ msgid "Passphrase"
 #~ msgstr "nesprávne heslo"
 
index 8f9d654..fb4ca7e 100644 (file)
--- a/po/sv.po
+++ b/po/sv.po
@@ -3189,6 +3189,11 @@ msgstr "spara och avsluta"
 msgid "show key fingerprint"
 msgstr "visa nyckelns fingeravtryck"
 
+#, fuzzy
+#| msgid "Enter the keygrip: "
+msgid "show the keygrip"
+msgstr "Ange nyckelhashen: "
+
 msgid "list key and user IDs"
 msgstr "lista nycklar och användaridentiteter"
 
@@ -3250,9 +3255,6 @@ msgstr "ändra utgångsdatumet för nyckeln eller valda undernycklar"
 msgid "flag the selected user ID as primary"
 msgstr "flagga vald användaridentitet som primär"
 
-msgid "toggle between the secret and public key listings"
-msgstr "växla mellan att lista hemliga och publika nycklar"
-
 msgid "list preferences (expert)"
 msgstr "lista inställningar (expertläge)"
 
@@ -3310,9 +3312,6 @@ msgstr "Den hemliga nyckeln finns tillgänglig.\n"
 msgid "Need the secret key to do this.\n"
 msgstr "Den hemliga nyckeln behövs för att göra detta.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Använd kommandot \"toggle\" först.\n"
-
 #, fuzzy
 #| msgid ""
 #| "* The `sign' command may be prefixed with an `l' for local signatures "
@@ -4327,7 +4326,7 @@ msgstr "Primära nyckelns fingeravtryck:"
 msgid "     Subkey fingerprint:"
 msgstr "   Undernyckelns fingeravtryck:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr "Primära nyckelns fingeravtryck:"
@@ -8645,6 +8644,12 @@ msgstr ""
 "Syntax: gpg-check-pattern [flaggor] mönsterfil\n"
 "Kontrollera en lösenfras angiven på standard in mot mönsterfilen\n"
 
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "växla mellan att lista hemliga och publika nycklar"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Använd kommandot \"toggle\" först.\n"
+
 #~ msgid "Passphrase"
 #~ msgstr "Lösenfras"
 
index 9ce59ce..3ab774a 100644 (file)
--- a/po/tr.po
+++ b/po/tr.po
@@ -3126,6 +3126,10 @@ msgstr "kaydet ve çık"
 msgid "show key fingerprint"
 msgstr "parmakizini gösterir"
 
+#, fuzzy
+msgid "show the keygrip"
+msgstr "Simgelemi giriniz: "
+
 msgid "list key and user IDs"
 msgstr "anahtarı ve kullanıcı kimliğini gösterir"
 
@@ -3190,9 +3194,6 @@ msgstr ""
 msgid "flag the selected user ID as primary"
 msgstr "seçili kullanıcı kimliğini asıl olarak imler"
 
-msgid "toggle between the secret and public key listings"
-msgstr "genel ve gizli anahtar listeleri arasında yer değiştirir"
-
 msgid "list preferences (expert)"
 msgstr "tercihleri listeler (uzman)"
 
@@ -3250,9 +3251,6 @@ msgstr "Gizli anahtar mevcut.\n"
 msgid "Need the secret key to do this.\n"
 msgstr "Bunu yapmak için gizli anahtar gerekli.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "lütfen önce \"seçmece\" komutunu kullanın.\n"
-
 #, fuzzy
 #| msgid ""
 #| "* The `sign' command may be prefixed with an `l' for local signatures "
@@ -4282,7 +4280,7 @@ msgstr "Birincil anahtar parmak izi:"
 msgid "     Subkey fingerprint:"
 msgstr "Yardımcı anahtar parmak izi:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr "Birincil anahtar parmak izi:"
@@ -8570,6 +8568,12 @@ msgstr ""
 "Standart girdiden verilen anahtar parolasını örüntü dosyasıyla "
 "karşılaştırır\n"
 
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "genel ve gizli anahtar listeleri arasında yer değiştirir"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "lütfen önce \"seçmece\" komutunu kullanın.\n"
+
 #~ msgid "Passphrase"
 #~ msgstr "Anahtar Parolası"
 
index 865a292..b523414 100644 (file)
--- a/po/uk.po
+++ b/po/uk.po
@@ -2993,6 +2993,11 @@ msgstr "зберегти і вийти"
 msgid "show key fingerprint"
 msgstr "показати відбиток ключа"
 
+#, fuzzy
+#| msgid "Enter the keygrip: "
+msgid "show the keygrip"
+msgstr "Вкажіть keygrip: "
+
 msgid "list key and user IDs"
 msgstr "показати список ключів та ідентифікаторів користувача"
 
@@ -3057,9 +3062,6 @@ msgstr "змінити дату завершення строку дії клю
 msgid "flag the selected user ID as primary"
 msgstr "позначити вибраний ідентифікатор користувача як основний"
 
-msgid "toggle between the secret and public key listings"
-msgstr "перемкнутися між списками закритих і відкритих ключів"
-
 msgid "list preferences (expert)"
 msgstr "список переваг (експертний)"
 
@@ -3117,9 +3119,6 @@ msgstr "Доступний закритий ключ.\n"
 msgid "Need the secret key to do this.\n"
 msgstr "Для цього потрібен закритий ключ.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "Скористайтеся спочатку командою «toggle».\n"
-
 msgid ""
 "* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
@@ -4083,7 +4082,7 @@ msgstr "Основний відбиток ключа:"
 msgid "     Subkey fingerprint:"
 msgstr "      Відбиток підключа:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr "Відбиток основного ключа:"
@@ -8039,6 +8038,12 @@ msgstr ""
 "Синтаксис: gpg-check-pattern [параметри] файл_шаблонів\n"
 "Перевірити пароль, вказаний у stdin, за допомогою файла_шаблонів\n"
 
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "перемкнутися між списками закритих і відкритих ключів"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "Скористайтеся спочатку командою «toggle».\n"
+
 #~ msgid "Passphrase"
 #~ msgstr "Пароль"
 
index caa9568..ed873ba 100644 (file)
@@ -3063,6 +3063,10 @@ msgstr "保存并离开"
 msgid "show key fingerprint"
 msgstr "显示密钥指纹"
 
+#, fuzzy
+msgid "show the keygrip"
+msgstr "输入注记:"
+
 msgid "list key and user IDs"
 msgstr "列出密钥和用户标识"
 
@@ -3123,9 +3127,6 @@ msgstr "变更密钥或所选子钥的使用期限"
 msgid "flag the selected user ID as primary"
 msgstr "将所选的用户标识设为首选用户标识"
 
-msgid "toggle between the secret and public key listings"
-msgstr "在私钥和公钥清单间切换"
-
 msgid "list preferences (expert)"
 msgstr "列出首选项(专家模式)"
 
@@ -3177,9 +3178,6 @@ msgstr "私钥可用。\n"
 msgid "Need the secret key to do this.\n"
 msgstr "要有私钥才能这么做。\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "请先使用“toggle”指令。\n"
-
 #, fuzzy
 #| msgid ""
 #| "* The `sign' command may be prefixed with an `l' for local signatures "
@@ -4152,7 +4150,7 @@ msgstr "主钥指纹:"
 msgid "     Subkey fingerprint:"
 msgstr "子钥指纹:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr " 主钥指纹:"
@@ -8178,6 +8176,12 @@ msgid ""
 "Check a passphrase given on stdin against the patternfile\n"
 msgstr ""
 
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "在私钥和公钥清单间切换"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "请先使用“toggle”指令。\n"
+
 #, fuzzy
 #~ msgid "Passphrase"
 #~ msgstr "错误的密码"
index 18d8b09..ac86d58 100644 (file)
@@ -2897,6 +2897,11 @@ msgstr "儲存並離開"
 msgid "show key fingerprint"
 msgstr "顯示金鑰指紋"
 
+#, fuzzy
+#| msgid "Enter the keygrip: "
+msgid "show the keygrip"
+msgstr "請輸入金鑰鑰柄: "
+
 msgid "list key and user IDs"
 msgstr "列出金鑰和使用者 ID"
 
@@ -2957,9 +2962,6 @@ msgstr "變更金鑰或所選子鑰的使用期限"
 msgid "flag the selected user ID as primary"
 msgstr "把所選的使用者 ID 標為主要"
 
-msgid "toggle between the secret and public key listings"
-msgstr "在私鑰清單和公鑰清單間切換"
-
 msgid "list preferences (expert)"
 msgstr "列出偏好 (專家模式)"
 
@@ -3011,9 +3013,6 @@ msgstr "私鑰可用.\n"
 msgid "Need the secret key to do this.\n"
 msgstr "要有私鑰纔能這麼做.\n"
 
-msgid "Please use the command \"toggle\" first.\n"
-msgstr "請先使用 \"toggle\" 指令.\n"
-
 msgid ""
 "* The 'sign' command may be prefixed with an 'l' for local signatures "
 "(lsign),\n"
@@ -3949,7 +3948,7 @@ msgstr "               主鑰指紋:"
 msgid "     Subkey fingerprint:"
 msgstr "               子鑰指紋:"
 
-#. TRANSLATORS: this should fit into 24 bytes to that the
+#. TRANSLATORS: this should fit into 24 bytes so that the
 #. * fingerprint data is properly aligned with the user ID
 msgid " Primary key fingerprint:"
 msgstr "                主鑰指紋:"
@@ -7775,6 +7774,12 @@ msgstr ""
 "語法: gpg-check-pattern [選項] 樣式檔案\n"
 "用樣式檔案來檢查由標準輸入給定的密語\n"
 
+#~ msgid "toggle between the secret and public key listings"
+#~ msgstr "在私鑰清單和公鑰清單間切換"
+
+#~ msgid "Please use the command \"toggle\" first.\n"
+#~ msgstr "請先使用 \"toggle\" 指令.\n"
+
 #~ msgid "Passphrase"
 #~ msgstr "密語"
 
index 6212e61..80e4c0f 100644 (file)
@@ -49,22 +49,3 @@ scdaemon_LDADD = $(libcommonpth) \
        $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(NPTH_LIBS) \
        $(LIBUSB_LIBS) $(GPG_ERROR_LIBS) \
         $(LIBINTL) $(DL_LIBS) $(NETLIBS) $(LIBICONV) $(resource_objs)
-
-# Removed for now: We need to decide whether it makes sense to
-# continue it at all, given that gpg has now all required
-# functionality.
-#sc_copykeys_SOURCES = \
-#      sc-copykeys.c scdaemon.h \
-#      apdu.c apdu.h \
-#      ccid-driver.c ccid-driver.h \
-#      iso7816.c iso7816.h \
-#      atr.c atr.h \
-#      app.c app-common.h app-help.c $(card_apps)
-#
-#sc_copykeys_LDADD = \
-#      ../common/libcommon.a \
-#      ../common/libsimple-pwquery.a \
-#      $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(NPTH_LIBS) \
-#       $(LIBUSB_LIBS) \
-#        -lgpg-error @LIBINTL@ @DL_LIBS@
-#
index 467389d..461c710 100644 (file)
 #include "options.h"
 #include "errors.h"
 #include "memory.h"
-#include "util.h"
 #include "cardglue.h"
 #else /* GNUPG_MAJOR_VERSION != 1 */
 #include "scdaemon.h"
 #endif /* GNUPG_MAJOR_VERSION != 1 */
 
+#include "util.h"
 #include "i18n.h"
 #include "iso7816.h"
 #include "app-common.h"
 #include "tlv.h"
 #include "host2net.h"
+#include "openpgpdefs.h"
 
 
 /* A table describing the DOs of the card.  */
@@ -125,7 +126,6 @@ static struct {
 typedef enum
   {
     KEY_TYPE_ECC,
-    KEY_TYPE_EDDSA,
     KEY_TYPE_RSA,
   }
 key_type_t;
@@ -143,18 +143,6 @@ typedef enum
 rsa_key_format_t;
 
 
-/* Elliptic Curves.  */
-enum
-  {
-    CURVE_NIST_P256,
-    CURVE_NIST_P384,
-    CURVE_NIST_P521,
-    CURVE_SEC_P256K1,
-    CURVE_ED25519,
-    CURVE_UNKNOWN,
-  };
-
-
 /* One cache item for DOs.  */
 struct cache_s {
   struct cache_s *next;
@@ -240,15 +228,14 @@ struct app_local_s {
         rsa_key_format_t format;
       } rsa;
       struct {
-        int curve;
+        const char *oid;
+        int flags;
       } ecc;
-      struct {
-        int curve;
-      } eddsa;
     };
    } keyattr[3];
 };
 
+#define ECC_FLAG_DJB_TWEAK (1 << 0)
 
 
 /***** Local prototypes  *****/
@@ -744,25 +731,12 @@ parse_login_data (app_t app)
 }
 
 
-static unsigned char
-get_algo_byte (int keynumber, key_type_t key_type)
-{
-  if (key_type == KEY_TYPE_ECC && keynumber != 1)
-    return 19;
-  else if (key_type == KEY_TYPE_ECC && keynumber == 1)
-    return 18;
-  else if (key_type == KEY_TYPE_EDDSA)
-    return 22;
-  else
-    return 1;  /* RSA */
-}
-
 #define MAX_ARGS_STORE_FPR 3
 
 /* Note, that FPR must be at least 20 bytes. */
 static gpg_error_t
 store_fpr (app_t app, int keynumber, u32 timestamp, unsigned char *fpr,
-           key_type_t key_type, ...)
+           int algo, ...)
 {
   unsigned int n, nbits;
   unsigned char *buffer, *p;
@@ -775,21 +749,17 @@ store_fpr (app_t app, int keynumber, u32 timestamp, unsigned char *fpr,
   int i;
 
   n = 6;    /* key packet version, 4-byte timestamps, and algorithm */
-  if (keynumber == 1 && key_type == KEY_TYPE_ECC)
+  if (algo == PUBKEY_ALGO_ECDH)
     argc = 3;
   else
     argc = 2;
 
-  va_start (ap, key_type);
+  va_start (ap, algo);
   for (i = 0; i < argc; i++)
     {
       m[i] = va_arg (ap, const unsigned char *);
       mlen[i] = va_arg (ap, size_t);
-      if (key_type != KEY_TYPE_EDDSA)
-        /* strip off leading zeroes */
-        for (; mlen[i] && !*m[i]; mlen[i]--, m[i]++)
-          ;
-      if (key_type == KEY_TYPE_RSA || i == 1)
+      if (algo == PUBKEY_ALGO_RSA || i == 1)
         n += 2;
       n += mlen[i];
     }
@@ -807,11 +777,11 @@ store_fpr (app_t app, int keynumber, u32 timestamp, unsigned char *fpr,
   *p++ = timestamp >> 16;
   *p++ = timestamp >>  8;
   *p++ = timestamp;
-  *p++ = get_algo_byte (keynumber, key_type);
+  *p++ = algo;
 
   for (i = 0; i < argc; i++)
     {
-      if (key_type == KEY_TYPE_RSA || i == 1)
+      if (algo == PUBKEY_ALGO_RSA || i == 1)
         {
           nbits = count_bits (m[i], mlen[i]);
           *p++ = nbits >> 8;
@@ -923,71 +893,29 @@ send_key_data (ctrl_t ctrl, const char *name,
 
 
 static void
-get_ecc_key_parameters (int curve, int *r_n_bits, const char **r_curve_oid)
-{
-  if (curve == CURVE_NIST_P256)
-    {
-      *r_n_bits = 256;
-      *r_curve_oid = "1.2.840.10045.3.1.7";
-    }
-  else if (curve == CURVE_NIST_P384)
-    {
-      *r_n_bits = 384;
-      *r_curve_oid = "1.3.132.0.34";
-    }
-  else if (curve == CURVE_NIST_P521)
-    {
-      *r_n_bits = 521;
-      *r_curve_oid = "1.3.132.0.35";
-    }
-  else if (curve == CURVE_SEC_P256K1)
-    {
-      *r_n_bits = 256;
-      *r_curve_oid = "1.3.132.0.10";
-    }
-  else if (curve == CURVE_ED25519)
-    {
-      *r_n_bits = 255;
-      *r_curve_oid = "1.3.6.1.4.1.11591.15.1";
-    }
-  else
-    {
-      *r_n_bits = 0;
-      *r_curve_oid = "1.3.6.1.4.1.11591.2.12242973"; /* gnu.gnupg.badoid */
-    }
-}
-
-static void
-send_key_attr (ctrl_t ctrl, app_t app, const char *keyword, int number)
+send_key_attr (ctrl_t ctrl, app_t app, const char *keyword, int keyno)
 {
   char buffer[200];
-  int n_bits;
-  const char *curve_oid;
 
-  assert (number >=0 && number < DIM(app->app_local->keyattr));
+  assert (keyno >=0 && keyno < DIM(app->app_local->keyattr));
 
-  if (app->app_local->keyattr[number].key_type == KEY_TYPE_RSA)
-    snprintf (buffer, sizeof buffer, "%d 1 %u %u %d",
-              number+1,
-              app->app_local->keyattr[number].rsa.n_bits,
-              app->app_local->keyattr[number].rsa.e_bits,
-              app->app_local->keyattr[number].rsa.format);
-  else if (app->app_local->keyattr[number].key_type == KEY_TYPE_ECC)
-    {
-      get_ecc_key_parameters (app->app_local->keyattr[number].ecc.curve,
-                              &n_bits, &curve_oid);
-      snprintf (buffer, sizeof buffer, "%d %d %u %s",
-                number+1, number==1? 18: 19, n_bits, curve_oid);
-    }
-  else if (app->app_local->keyattr[number].key_type == KEY_TYPE_EDDSA)
+  if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_RSA)
+    snprintf (buffer, sizeof buffer, "%d 1 rsa%u %u %d",
+              keyno+1,
+              app->app_local->keyattr[keyno].rsa.n_bits,
+              app->app_local->keyattr[keyno].rsa.e_bits,
+              app->app_local->keyattr[keyno].rsa.format);
+  else if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_ECC)
     {
-      get_ecc_key_parameters (app->app_local->keyattr[number].eddsa.curve,
-                              &n_bits, &curve_oid);
-      snprintf (buffer, sizeof buffer, "%d 22 %u %s",
-                number+1, n_bits, curve_oid);
+      snprintf (buffer, sizeof buffer, "%d %d %s",
+                keyno+1,
+                keyno==1? PUBKEY_ALGO_ECDH :
+                app->app_local->keyattr[keyno].ecc.flags?
+                PUBKEY_ALGO_EDDSA : PUBKEY_ALGO_ECDSA,
+                openpgp_oid_to_curve (app->app_local->keyattr[keyno].ecc.oid, 0));
     }
   else
-    snprintf (buffer, sizeof buffer, "0 0 UNKNOWN");
+    snprintf (buffer, sizeof buffer, "%d 0 0 UNKNOWN", keyno+1);
 
   send_status_direct (ctrl, keyword, buffer);
 }
@@ -1071,8 +999,9 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
                 app->app_local->extcap.max_certlen_3,
                 app->app_local->extcap.algo_attr_change,
                 (app->app_local->extcap.sm_supported
-                 ? (app->app_local->extcap.sm_algo == 0? 2 :
-                    (app->app_local->extcap.sm_algo == 1? 7 : 9))
+                 ? (app->app_local->extcap.sm_algo == 0? CIPHER_ALGO_3DES :
+                    (app->app_local->extcap.sm_algo == 1?
+                     CIPHER_ALGO_AES : CIPHER_ALGO_AES256))
                  : 0),
                 app->app_local->status_indicator,
                 app->app_local->extcap.has_decrypt,
@@ -1291,24 +1220,6 @@ retrieve_key_material (FILE *fp, const char *hexkeyid,
 #endif /*GNUPG_MAJOR_VERSION > 1*/
 
 
-static const char *
-get_curve_name (int curve)
-{
-  if (curve == CURVE_NIST_P256)
-    return "NIST P-256";
-  else if (curve == CURVE_NIST_P384)
-    return "NIST P-384";
-  else if (curve == CURVE_NIST_P521)
-    return "NIST P-521";
-  else if (curve == CURVE_SEC_P256K1)
-    return "secp256k1";
-  else if (curve == CURVE_ED25519)
-    return "Ed25519";
-  else
-    return "unknown";
-}
-
-
 /* Get the public key for KEYNO and store it as an S-expresion with
    the APP handle.  On error that field gets cleared.  If we already
    know about the public key we will just return.  Note that this does
@@ -1468,109 +1379,85 @@ get_public_key (app_t app, int keyno)
        }
     }
 
-
-  mbuf = xtrymalloc ( mlen + 1);
+  mbuf = xtrymalloc (mlen + 1);
   if (!mbuf)
     {
       err = gpg_error_from_syserror ();
       goto leave;
     }
-  /* Prepend numbers with a 0 if needed.  */
-  if (app->app_local->keyattr[keyno].key_type != KEY_TYPE_EDDSA
+
+  if ((app->app_local->keyattr[keyno].key_type == KEY_TYPE_RSA
+       || (app->app_local->keyattr[keyno].key_type == KEY_TYPE_ECC
+           && !app->app_local->keyattr[keyno].ecc.flags))
       && mlen && (*m & 0x80))
-    {
+    {               /* Prepend numbers with a 0 if needed for MPI.  */
       *mbuf = 0;
       memcpy (mbuf+1, m, mlen);
       mlen++;
     }
-  else
-    memcpy (mbuf, m, mlen);
-
-  ebuf = xtrymalloc ( elen + 1);
-  if (!ebuf)
-    {
-      err = gpg_error_from_syserror ();
-      goto leave;
-    }
-  /* Prepend numbers with a 0 if needed.  */
-  if (elen && (*e & 0x80))
-    {
-      *ebuf = 0;
-      memcpy (ebuf+1, e, elen);
-      elen++;
+  else if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_ECC
+           && app->app_local->keyattr[keyno].ecc.flags)
+    {               /* Prepend 0x40 prefix.  */
+      *mbuf = 0x40;
+      memcpy (mbuf+1, m, mlen);
+      mlen++;
     }
   else
-    memcpy (ebuf, e, elen);
+    memcpy (mbuf, m, mlen);
 
   if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_RSA)
     {
-      err = gcry_sexp_build (&s_pkey, NULL, "(public-key(rsa(n%b)(e%b)))",
-                             (int)mlen, mbuf, (int)elen, ebuf);
-      if (err)
-        goto leave;
-
-      len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
-      keybuf = xtrymalloc (len);
-      if (!keybuf)
+      ebuf = xtrymalloc (elen + 1);
+      if (!ebuf)
         {
-          gcry_sexp_release (s_pkey);
           err = gpg_error_from_syserror ();
           goto leave;
         }
-      gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, keybuf, len);
-      gcry_sexp_release (s_pkey);
+      /* Prepend numbers with a 0 if needed.  */
+      if (elen && (*e & 0x80))
+        {
+          *ebuf = 0;
+          memcpy (ebuf+1, e, elen);
+          elen++;
+        }
+      else
+        memcpy (ebuf, e, elen);
+
+      err = gcry_sexp_build (&s_pkey, NULL, "(public-key(rsa(n%b)(e%b)))",
+                             (int)mlen, mbuf, (int)elen, ebuf);
     }
   else if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_ECC)
     {
-      const char *curve_name
-        = get_curve_name (app->app_local->keyattr[keyno].ecc.curve);
+      char *format;
 
-      err = gcry_sexp_build (&s_pkey, NULL,
-                             "(public-key(ecc(curve%s)(q%b)))",
-                             curve_name, (int)mlen, mbuf);
-      if (err)
-        goto leave;
-
-      len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
+      if (!app->app_local->keyattr[keyno].ecc.flags)
+        format = "(public-key(ecc(curve%s)(q%b)))";
+      else if (keyno == 1)
+        format = "(public-key(ecc(curve%s)(flags djb-tweak)(q%b)))";
+      else
+        format = "(public-key(ecc(curve%s)(flags eddsa)(q%b)))";
 
-      keybuf = xtrymalloc (len);
-      if (!keybuf)
-        {
-          gcry_sexp_release (s_pkey);
-          err = gpg_error_from_syserror ();
-          goto leave;
-        }
-      gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, keybuf, len);
-      gcry_sexp_release (s_pkey);
+      err = gcry_sexp_build (&s_pkey, NULL, format,
+                openpgp_oid_to_curve (app->app_local->keyattr[keyno].ecc.oid, 1),
+                             (int)mlen, mbuf);
     }
-  else if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_EDDSA)
-    {
-      const char *curve_name
-        = get_curve_name (app->app_local->keyattr[keyno].eddsa.curve);
+  else
+    err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
 
-      err = gcry_sexp_build (&s_pkey, NULL,
-                             "(public-key(ecc(curve%s)(flags eddsa)(q%b)))",
-                             curve_name, (int)mlen, mbuf);
-      if (err)
-        goto leave;
+  if (err)
+    goto leave;
 
-      len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
+  len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
 
-      keybuf = xtrymalloc (len);
-      if (!keybuf)
-        {
-          gcry_sexp_release (s_pkey);
-          err = gpg_error_from_syserror ();
-          goto leave;
-        }
-      gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, keybuf, len);
-      gcry_sexp_release (s_pkey);
-    }
-  else
+  keybuf = xtrymalloc (len);
+  if (!keybuf)
     {
-      err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+      gcry_sexp_release (s_pkey);
+      err = gpg_error_from_syserror ();
       goto leave;
     }
+  gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, keybuf, len);
+  gcry_sexp_release (s_pkey);
 
   app->app_local->pk[keyno].key = (unsigned char*)keybuf;
   app->app_local->pk[keyno].keylen = len - 1; /* Decrement for trailing '\0' */
@@ -2814,54 +2701,25 @@ build_ecc_privkey_template (app_t app, int keyno,
 /* Helper for do_writekley to change the size of a key.  Not ethat
    this deletes the entire key without asking.  */
 static gpg_error_t
-change_keyattr (app_t app, int keyno, unsigned int nbits,
+change_keyattr (app_t app, int keyno, const unsigned char *buf, size_t buflen,
                 gpg_error_t (*pincb)(void*, const char *, char **),
                 void *pincb_arg)
 {
   gpg_error_t err;
-  unsigned char *buffer;
-  size_t buflen;
-  void *relptr;
 
   assert (keyno >=0 && keyno <= 2);
 
-  if (nbits > 4096)
-    return gpg_error (GPG_ERR_TOO_LARGE);
-
-  /* Read the current attributes into a buffer.  */
-  relptr = get_one_do (app, 0xC1+keyno, &buffer, &buflen, NULL);
-  if (!relptr)
-    return gpg_error (GPG_ERR_CARD);
-  if (buflen < 6 || buffer[0] != 1)
-    {
-      /* Attriutes too short or not an RSA key.  */
-      xfree (relptr);
-      return gpg_error (GPG_ERR_CARD);
-    }
-
-  /* We only change n_bits and don't touch anything else.  Before we
-     do so, we round up NBITS to a sensible way in the same way as
-     gpg's key generation does it.  This may help to sort out problems
-     with a few bits too short keys.  */
-  nbits = ((nbits + 31) / 32) * 32;
-  buffer[1] = (nbits >> 8);
-  buffer[2] = nbits;
-
   /* Prepare for storing the key.  */
   err = verify_chv3 (app, pincb, pincb_arg);
   if (err)
-    {
-      xfree (relptr);
-      return err;
-    }
+    return err;
 
   /* Change the attribute.  */
-  err = iso7816_put_data (app->slot, 0, 0xC1+keyno, buffer, buflen);
-  xfree (relptr);
+  err = iso7816_put_data (app->slot, 0, 0xC1+keyno, buf, buflen);
   if (err)
-    log_error ("error changing size of key %d to %u bits\n", keyno+1, nbits);
+    log_error ("error changing key attribute (key=%d)\n", keyno+1);
   else
-    log_info ("size of key %d changed to %u bits\n", keyno+1, nbits);
+    log_info ("key attribute changed (key=%d)\n", keyno+1);
   flush_cache (app);
   parse_algorithm_attribute (app, keyno);
   app->did_chv1 = 0;
@@ -2871,18 +2729,21 @@ change_keyattr (app_t app, int keyno, unsigned int nbits,
 }
 
 
-/* Helper to process an setattr command for name KEY-ATTR.  It expects
-   a string "--force <keyno> <algo> <nbits>" in (VALUE,VALUELEN).  */
+/* Helper to process an setattr command for name KEY-ATTR.
+   In (VALUE,VALUELEN), it expects following string:
+        RSA: "--force <keyno> <algo> rsa<nbits>"
+        ECC: "--force <keyno> <algo> <curvename>"
+  */
 static gpg_error_t
 change_keyattr_from_string (app_t app,
                             gpg_error_t (*pincb)(void*, const char *, char **),
                             void *pincb_arg,
                             const void *value, size_t valuelen)
 {
-  gpg_error_t err;
+  gpg_error_t err = 0;
   char *string;
   int keyno, algo;
-  unsigned int nbits;
+  int n = 0;
 
   /* VALUE is expected to be a string but not guaranteed to be
      terminated.  Thus copy it to an allocated buffer first. */
@@ -2895,17 +2756,91 @@ change_keyattr_from_string (app_t app,
   /* Because this function deletes the key we require the string
      "--force" in the data to make clear that something serious might
      happen.  */
-  if (sscanf (string, " --force %d %d %u", &keyno, &algo, &nbits) != 3)
-    err = gpg_error (GPG_ERR_INV_DATA);
-  else if (keyno < 1 || keyno > 3)
+  sscanf (string, " --force %d %d %n", &keyno, &algo, &n);
+  if (n < 13)
+    {
+      err = gpg_error (GPG_ERR_INV_DATA);
+      goto leave;
+    }
+
+  if (keyno < 1 || keyno > 3)
     err = gpg_error (GPG_ERR_INV_ID);
-  else if (algo != 1)
-    err = gpg_error (GPG_ERR_PUBKEY_ALGO); /* Not RSA.  */
-  else if (nbits < 1024)
-    err = gpg_error (GPG_ERR_TOO_SHORT);
+  else if (algo == PUBKEY_ALGO_RSA)
+    {
+      unsigned int nbits;
+
+      errno = 0;
+      nbits = strtoul (string+n+3, NULL, 10);
+      if (errno)
+        err = gpg_error (GPG_ERR_INV_DATA);
+      else if (nbits < 1024)
+        err = gpg_error (GPG_ERR_TOO_SHORT);
+      else if (nbits > 4096)
+        err = gpg_error (GPG_ERR_TOO_LARGE);
+      else
+        {
+          unsigned char *buf;
+          size_t buflen;
+          void *relptr;
+
+          /* Read the current attributes into a buffer.  */
+          relptr = get_one_do (app, 0xC1+keyno, &buf, &buflen, NULL);
+          if (!relptr)
+            {
+              err = gpg_error (GPG_ERR_CARD);
+              goto leave;
+            }
+          if (buflen < 6 || buf[0] != PUBKEY_ALGO_RSA)
+            {
+              /* Attriutes too short or not an RSA key.  */
+              xfree (relptr);
+              err = gpg_error (GPG_ERR_CARD);
+              goto leave;
+            }
+
+          /* We only change n_bits and don't touch anything else.  Before we
+             do so, we round up NBITS to a sensible way in the same way as
+             gpg's key generation does it.  This may help to sort out problems
+             with a few bits too short keys.  */
+          nbits = ((nbits + 31) / 32) * 32;
+          buf[1] = (nbits >> 8);
+          buf[2] = nbits;
+          err = change_keyattr (app, keyno-1, buf, buflen, pincb, pincb_arg);
+          xfree (relptr);
+        }
+    }
+  else if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA
+           || algo == PUBKEY_ALGO_EDDSA)
+    {
+      const char *oidstr;
+
+      oidstr = openpgp_curve_to_oid (string+n, NULL);
+      if (!oidstr)
+        err = gpg_error (GPG_ERR_INV_DATA);
+      else
+        {
+          gcry_mpi_t m;
+
+          err = openpgp_oid_from_str (oidstr, &m);
+          if (!err)
+            {
+              unsigned int len;
+              const unsigned char *buf = gcry_mpi_get_opaque (m, &len);
+
+              /* We have enough room at STRING.  */
+              len = buf[0];
+              string[0] = algo;
+              memcpy (string+1, buf+1, len++);
+              err = change_keyattr (app, keyno-1, string, len,
+                                    pincb, pincb_arg);
+              gcry_mpi_release (m);
+            }
+        }
+    }
   else
-    err = change_keyattr (app, keyno-1, nbits, pincb, pincb_arg);
+    err = gpg_error (GPG_ERR_PUBKEY_ALGO);
 
+ leave:
   xfree (string);
   return err;
 }
@@ -2933,6 +2868,13 @@ rsa_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
   unsigned char fprbuf[20];
   u32 created_at = 0;
 
+  if (app->app_local->keyattr[keyno].key_type != KEY_TYPE_RSA)
+    {
+      log_error (_("unsupported algorithm: %s"), "RSA");
+      err = gpg_error (GPG_ERR_INV_VALUE);
+      goto leave;
+    }
+
   last_depth1 = depth;
   while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
          && depth && depth >= last_depth1)
@@ -3028,14 +2970,6 @@ rsa_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
   if (opt.verbose)
     log_info ("RSA modulus size is %u bits (%u bytes)\n",
               nbits, (unsigned int)rsa_n_len);
-  if (nbits && nbits != maxbits
-      && app->app_local->extcap.algo_attr_change)
-    {
-      /* Try to switch the key to a new length.  */
-      err = change_keyattr (app, keyno, nbits, pincb, pincb_arg);
-      if (!err)
-        maxbits = app->app_local->keyattr[keyno].rsa.n_bits;
-    }
   if (nbits != maxbits)
     {
       log_error (_("RSA modulus missing or not of size %d bits\n"),
@@ -3205,7 +3139,7 @@ rsa_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
       goto leave;
     }
 
-  err = store_fpr (app, keyno, created_at, fprbuf, KEY_TYPE_RSA,
+  err = store_fpr (app, keyno, created_at, fprbuf, PUBKEY_ALGO_RSA,
                    rsa_n, rsa_n_len, rsa_e, rsa_e_len);
   if (err)
     goto leave;
@@ -3229,11 +3163,10 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
   const unsigned char *ecc_q = NULL;
   const unsigned char *ecc_d = NULL;
   size_t ecc_q_len, ecc_d_len;
-  unsigned char *template = NULL;
-  size_t template_len;
-  unsigned char fprbuf[20];
   u32 created_at = 0;
-  int curve = CURVE_UNKNOWN;
+  const char *oidstr = NULL;
+  int flag_djb_tweak = 0;
+  int algo;
 
   /* (private-key(ecc(curve%s)(q%m)(d%m))(created-at%d)):
      curve = "NIST P-256" */
@@ -3255,21 +3188,34 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
 
       if (tok && toklen == 5 && !memcmp (tok, "curve", 5))
         {
+          unsigned char *curve;
+
           if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
             goto leave;
 
-          if (tok && toklen == 10 && !memcmp (tok, "NIST P-256", 10))
-            curve = CURVE_NIST_P256;
-          else if (tok && toklen == 9 && !memcmp (tok, "secp256k1", 9))
-            curve = CURVE_SEC_P256K1;
-          else if (tok && toklen == 7 && !memcmp (tok, "Ed25519", 7))
-            curve = CURVE_ED25519;
-          else
+          curve = xtrymalloc (toklen+1);
+          if (!curve)
             {
-              log_error (_("unsupported curve\n"));
-              err = gpg_error (GPG_ERR_INV_VALUE);
+              err = gpg_error_from_syserror ();
               goto leave;
             }
+
+          memcpy (curve, tok, toklen);
+          curve[toklen] = 0;
+          oidstr = openpgp_curve_to_oid (curve, NULL);
+          xfree (curve);
+        }
+      else if (tok && toklen == 5 && !memcmp (tok, "flags", 5))
+        {
+          if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+            goto leave;
+
+          if (tok)
+            {
+              if ((toklen == 5 && !memcmp (tok, "eddsa", 5))
+                  || (toklen == 9 && !memcmp (tok, "djb-tweak", 9)))
+                flag_djb_tweak = 1;
+            }
         }
       else if (tok && toklen == 1)
         {
@@ -3289,7 +3235,7 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
             }
           if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
             goto leave;
-          if (tok && buf2 && curve != CURVE_ED25519)
+          if (tok && buf2 && !flag_djb_tweak)
             /* It's MPI.  Strip off leading zero bytes and save. */
             for (;toklen && !*tok; toklen--, tok++)
               ;
@@ -3340,12 +3286,33 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
 
   /* Check that we have all parameters and that they match the card
      description. */
+  if (!oidstr)
+    {
+      log_error (_("unsupported curve\n"));
+      err = gpg_error (GPG_ERR_INV_VALUE);
+      goto leave;
+    }
   if (!created_at)
     {
       log_error (_("creation timestamp missing\n"));
       err = gpg_error (GPG_ERR_INV_VALUE);
       goto leave;
     }
+  if (flag_djb_tweak && keyno != 1)
+    algo = PUBKEY_ALGO_EDDSA;
+  else if (keyno == 1)
+    algo = PUBKEY_ALGO_ECDH;
+  else
+    algo = PUBKEY_ALGO_ECDSA;
+
+  if (app->app_local->keyattr[keyno].key_type != KEY_TYPE_ECC
+      || app->app_local->keyattr[keyno].ecc.oid != oidstr
+      || app->app_local->keyattr[keyno].ecc.flags != flag_djb_tweak)
+    {
+      log_error ("key attribute on card doesn't match\n");
+      err = gpg_error (GPG_ERR_INV_VALUE);
+      goto leave;
+    }
 
   if (opt.verbose)
     log_info ("ECC private key size is %u bytes\n", (unsigned int)ecc_d_len);
@@ -3360,6 +3327,8 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
     {
       /* Build the private key template as described in section 4.3.3.7 of
          the OpenPGP card specs version 2.0.  */
+      unsigned char *template;
+      size_t template_len;
       int exmode;
 
       err = build_ecc_privkey_template (app, keyno,
@@ -3371,7 +3340,10 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
       /* Prepare for storing the key.  */
       err = verify_chv3 (app, pincb, pincb_arg);
       if (err)
-        goto leave;
+        {
+          xfree (template);
+          goto leave;
+        }
 
       /* Store the key. */
       if (app->app_local->cardcap.ext_lc_le && template_len > 254)
@@ -3382,32 +3354,43 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
         exmode = 0;
       err = iso7816_put_data_odd (app->slot, exmode, 0x3fff,
                                   template, template_len);
+      xfree (template);
     }
   else
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+    err = gpg_error (GPG_ERR_NOT_SUPPORTED);
 
   if (err)
     {
       log_error (_("failed to store the key: %s\n"), gpg_strerror (err));
       goto leave;
     }
+  else
+    {
+      gcry_mpi_t oid;
+      const unsigned char *oidbuf;
+      unsigned int n;
+      size_t oid_len;
+      unsigned char fprbuf[20];
 
-  err = store_fpr (app, keyno, created_at, fprbuf,
-                   curve == CURVE_ED25519 ? KEY_TYPE_EDDSA : KEY_TYPE_ECC,
-                   curve == CURVE_ED25519 ?
-                   "\x09\x2b\x06\x01\x04\x01\xda\x47\x0f\x01"
-                   : curve == CURVE_NIST_P256 ?
-                   "\x08\x2a\x86\x48\xce\x3d\x03\x01\x07"
-                   : "\x05\x2b\x81\x04\x00\x0a",
-                   (size_t)(curve == CURVE_ED25519 ? 10
-                            : curve == CURVE_NIST_P256? 9 : 6),
-                   ecc_q, ecc_q_len, "\x03\x01\x08\x07", (size_t)4);
-  if (err)
-    goto leave;
+      err = openpgp_oid_from_str (oidstr, &oid);
+      if (err)
+        goto leave;
 
+      oidbuf = gcry_mpi_get_opaque (oid, &n);
+      oid_len = (n+7)/8;
+      if (!oidbuf)
+        {
+          err = gpg_error_from_syserror ();
+          gcry_mpi_release (oid);
+          goto leave;
+        }
+      err = store_fpr (app, keyno, created_at, fprbuf, algo,
+                       oidbuf, oid_len, ecc_q, ecc_q_len,
+                       "\x03\x01\x08\x07", (size_t)4);
+      gcry_mpi_release (oid);
+    }
 
  leave:
-  xfree (template);
   return err;
 }
 
@@ -3475,10 +3458,7 @@ do_writekey (app_t app, ctrl_t ctrl,
     goto leave;
   if (tok && toklen == 3 && memcmp ("rsa", tok, toklen) == 0)
     err = rsa_writekey (app, pincb, pincb_arg, keyno, buf, buflen, depth);
-  else if (tok
-           && ((toklen == 3 && memcmp ("ecc", tok, toklen) == 0)
-               || (toklen == 4 && memcmp ("ecdh", tok, toklen) == 0)
-               || (toklen == 5 && memcmp ("ecdsa", tok, toklen) == 0)))
+  else if (tok && toklen == 3 && memcmp ("ecc", tok, toklen) == 0)
     err = ecc_writekey (app, pincb, pincb_arg, keyno, buf, buflen, depth);
   else
     {
@@ -3613,7 +3593,7 @@ do_genkey (app_t app, ctrl_t ctrl,  const char *keynostr, unsigned int flags,
   send_status_info (ctrl, "KEY-CREATED-AT",
                     numbuf, (size_t)strlen(numbuf), NULL, 0);
 
-  rc = store_fpr (app, keyno, (u32)created_at, fprbuf, KEY_TYPE_RSA,
+  rc = store_fpr (app, keyno, (u32)created_at, fprbuf, PUBKEY_ALGO_RSA,
                   m, mlen, e, elen);
   if (rc)
     goto leave;
@@ -3966,18 +3946,21 @@ do_auth (app_t app, const char *keyidstr,
       && indatalen > 101) /* For a 2048 bit key. */
     return gpg_error (GPG_ERR_INV_VALUE);
 
-  if (app->app_local->keyattr[2].key_type == KEY_TYPE_ECC
-      && (indatalen == 51 || indatalen == 67 || indatalen == 83))
-    {
-      const char *p = (const char *)indata + 19;
-      indata = p;
-      indatalen -= 19;
-    }
-  else if (app->app_local->keyattr[2].key_type == KEY_TYPE_EDDSA)
+  if (app->app_local->keyattr[2].key_type == KEY_TYPE_ECC)
     {
-      const char *p = (const char *)indata + 15;
-      indata = p;
-      indatalen -= 15;
+      if (!app->app_local->keyattr[2].ecc.flags
+          && (indatalen == 51 || indatalen == 67 || indatalen == 83))
+        {
+          const char *p = (const char *)indata + 19;
+          indata = p;
+          indatalen -= 19;
+        }
+      else
+        {
+          const char *p = (const char *)indata + 15;
+          indata = p;
+          indatalen -= 15;
+        }
     }
 
   /* Check whether an OpenPGP card of any version has been requested. */
@@ -4101,7 +4084,10 @@ do_decipher (app_t app, const char *keyidstr,
   if (rc)
     return rc;
 
-  if (app->app_local->keyattr[1].key_type == KEY_TYPE_RSA)
+  if (indatalen == 16 + 1 || indatalen == 32 + 1)
+    /* PSO:DECIPHER with symmetric key.  */
+    padind = -1;
+  else if (app->app_local->keyattr[1].key_type == KEY_TYPE_RSA)
     {
       /* We might encounter a couple of leading zeroes in the
          cryptogram.  Due to internal use of MPIs these leading zeroes
@@ -4378,25 +4364,41 @@ parse_historical (struct app_local_s *apploc,
 }
 
 
-static int
-parse_ecc_curve (const unsigned char *buffer, size_t buflen)
+/*
+ * Check if the OID in an DER encoding is available by GnuPG/libgcrypt,
+ * and return the constant string in dotted decimal form.
+ * Return NULL if not available.
+ * The constant string is not allocated dynamically, never free it.
+ */
+static const char *
+ecc_oid (unsigned char *buf, size_t buflen)
 {
-  int curve;
-
-  if (buflen == 5 && buffer[5] == 0x22)
-    curve = CURVE_NIST_P384;
-  else if (buflen == 5 && buffer[5] == 0x23)
-    curve = CURVE_NIST_P521;
-  else if (buflen == 8)
-    curve = CURVE_NIST_P256;
-  else if (buflen == 5 && buffer[5] == 0x0a)
-    curve = CURVE_SEC_P256K1;
-  else if (buflen == 9)
-    curve = CURVE_ED25519;
-  else
-    curve = CURVE_UNKNOWN;
+  gcry_mpi_t oid;
+  char *oidstr;
+  const char *result;
+  unsigned char *oidbuf;
+
+  oidbuf = xtrymalloc (buflen + 1);
+  if (!oidbuf)
+    return NULL;
+
+  memcpy (oidbuf+1, buf, buflen);
+  oidbuf[0] = buflen;
+  oid = gcry_mpi_set_opaque (NULL, oidbuf, (buflen+1) * 8);
+  if (!oid)
+    {
+      xfree (oidbuf);
+      return NULL;
+    }
 
-  return curve;
+  oidstr = openpgp_oid_to_str (oid);
+  gcry_mpi_release (oid);
+  if (!oidstr)
+    return NULL;
+
+  result = openpgp_curve_to_oid (oidstr, NULL);
+  xfree (oidstr);
+  return result;
 }
 
 
@@ -4430,7 +4432,7 @@ parse_algorithm_attribute (app_t app, int keyno)
 
   if (opt.verbose)
     log_info ("Key-Attr-%s ..: ", desc[keyno]);
-  if (*buffer == 1 && (buflen == 5 || buflen == 6))
+  if (*buffer == PUBKEY_ALGO_RSA && (buflen == 5 || buflen == 6))
     {
       app->app_local->keyattr[keyno].rsa.n_bits = (buffer[1]<<8 | buffer[2]);
       app->app_local->keyattr[keyno].rsa.e_bits = (buffer[3]<<8 | buffer[4]);
@@ -4454,25 +4456,30 @@ parse_algorithm_attribute (app_t app, int keyno)
            app->app_local->keyattr[keyno].rsa.format == RSA_CRT?  "crt"  :
            app->app_local->keyattr[keyno].rsa.format == RSA_CRT_N?"crt+n":"?");
     }
-  else if (*buffer == 18 || *buffer == 19) /* ECDH or ECDSA */
+  else if (*buffer == PUBKEY_ALGO_ECDH || *buffer == PUBKEY_ALGO_ECDSA
+           || *buffer == PUBKEY_ALGO_EDDSA)
     {
-      app->app_local->keyattr[keyno].key_type = KEY_TYPE_ECC;
-      app->app_local->keyattr[keyno].ecc.curve
-        = parse_ecc_curve (buffer + 1, buflen - 1);
-      if (opt.verbose)
-        log_printf
-          ("ECC, curve=%s\n",
-           get_curve_name (app->app_local->keyattr[keyno].ecc.curve));
-    }
-  else if (*buffer == 22) /* EdDSA */
-    {
-      app->app_local->keyattr[keyno].key_type = KEY_TYPE_EDDSA;
-      app->app_local->keyattr[keyno].eddsa.curve
-        = parse_ecc_curve (buffer + 1, buflen - 1);
-      if (opt.verbose)
-        log_printf
-          ("EdDSA, curve=%s\n",
-           get_curve_name (app->app_local->keyattr[keyno].eddsa.curve));
+      const char *oid = ecc_oid (buffer + 1, buflen - 1);
+
+      if (!oid)
+        log_printhex ("Curve with OID not supported: ", buffer+1, buflen-1);
+      else
+        {
+          app->app_local->keyattr[keyno].key_type = KEY_TYPE_ECC;
+          app->app_local->keyattr[keyno].ecc.oid = oid;
+          if (*buffer == PUBKEY_ALGO_EDDSA
+              || (*buffer == PUBKEY_ALGO_ECDH
+                  && !strcmp (app->app_local->keyattr[keyno].ecc.oid,
+                              "1.3.6.1.4.1.3029.1.5.1")))
+            app->app_local->keyattr[keyno].ecc.flags = ECC_FLAG_DJB_TWEAK;
+          else
+            app->app_local->keyattr[keyno].ecc.flags = 0;
+          if (opt.verbose)
+            log_printf
+              ("ECC, curve=%s%s\n", app->app_local->keyattr[keyno].ecc.oid,
+               !app->app_local->keyattr[keyno].ecc.flags ? "":
+               keyno==1? " (djb-tweak)": " (eddsa)");
+        }
     }
   else if (opt.verbose)
     log_printhex ("", buffer, buflen);
diff --git a/scd/card-common.h b/scd/card-common.h
deleted file mode 100644 (file)
index 640cec7..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* card-common.h - Common declarations for all card types
- *     Copyright (C) 2001, 2002 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef CARD_COMMON_H
-#define CARD_COMMON_H
-
-/* Declaration of private data structure used by card-p15.c */
-struct p15private_s;
-
-
-struct card_ctx_s {
-  int reader;   /* used reader */
-  struct sc_context *ctx;
-  struct sc_card *scard;
-  struct sc_pkcs15_card *p15card; /* only if there is a pkcs15 application */
-  struct p15private_s *p15priv;   /* private data used by card-p15.c */
-
-  struct {
-    int initialized;  /* the card has been initialied and the function
-                         pointers may be used.  However for
-                         unsupported operations the particular
-                         function pointer is set to NULL */
-
-    int (*enum_keypairs) (CARD card, int idx,
-                          unsigned char *keygrip, char **keyid);
-    int (*enum_certs) (CARD card, int idx, char **certid, int *certtype);
-    int (*read_cert) (CARD card, const char *certidstr,
-                      unsigned char **cert, size_t *ncert);
-    int (*sign) (CARD card,
-                 const char *keyidstr, int hashalgo,
-                 int (pincb)(void*, const char *, char **),
-                 void *pincb_arg,
-                 const void *indata, size_t indatalen,
-                 unsigned char **outdata, size_t *outdatalen );
-    int (*decipher) (CARD card, const char *keyidstr,
-                     int (pincb)(void*, const char *, char **),
-                     void *pincb_arg,
-                     const void *indata, size_t indatalen,
-                     unsigned char **outdata, size_t *outdatalen);
-  } fnc;
-
-};
-
-/*-- card.c --*/
-gpg_error_t map_sc_err (int rc);
-int card_help_get_keygrip (ksba_cert_t cert, unsigned char *array);
-
-/*-- card-15.c --*/
-void p15_release_private_data (CARD card);
-
-/* constructors */
-void card_p15_bind (CARD card);
-void card_dinsig_bind (CARD card);
-
-
-#endif /*CARD_COMMON_H*/
diff --git a/scd/card-dinsig.c b/scd/card-dinsig.c
deleted file mode 100644 (file)
index 5be0061..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-/* card-dinsig.c - German signature law (DINSIG) functions
- *     Copyright (C) 2002 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/* The German signature law and its bylaw (SigG and SigV) is currently
-   used with an interface specification described in DIN V 66291-1.
-   The AID to be used is: 'D27600006601'.
-
-   The file IDs for certificates utilize the generic format:
-        Cxyz
-    C being the hex digit 'C' (12).
-    x being the service indicator:
-         '0' := SigG conform digital signature.
-         '1' := entity authentication.
-         '2' := key encipherment.
-         '3' := data encipherment.
-         '4' := key agreement.
-         other values are reserved for future use.
-    y being the security environment number using '0' for cards
-      not supporting a SE number.
-    z being the certificate type:
-         '0'        := C.CH (base certificate of ard holder) or C.ICC.
-         '1' .. '7' := C.CH (business or professional certificate
-                       of card holder.
-         '8' .. 'D' := C.CA (certificate of a CA issue by the Root-CA).
-         'E'        := C.RCA (self certified certificate of the Root-CA).
-         'F'        := reserved.
-
-   The file IDs used by default are:
-   '1F00'  EF.SSD (security service descriptor). [o,o]
-   '2F02'  EF.GDO (global data objects) [m,m]
-   'A000'  EF.PROT (signature log).  Cyclic file with 20 records of 53 byte.
-           Read and update after user authentication. [o,o]
-   'B000'  EF.PK.RCA.DS (public keys of Root-CA).  Size is 512b or size
-           of keys. [m (unless a 'C00E' is present),m]
-   'B001'  EF.PK.CA.DS (public keys of CAs).  Size is 512b or size
-           of keys. [o,o]
-   'C00n'  EF.C.CH.DS (digital signature certificate of card holder)
-           with n := 0 .. 7.  Size is 2k or size of cert.  Read and
-           update allowed after user authentication. [m,m]
-   'C00m'  EF.C.CA.DS (digital signature certificate of CA)
-           with m := 8 .. E.  Size is 1k or size of cert.  Read always
-           allowed, update after uder authentication. [o,o]
-   'C100'  EF.C.ICC.AUT (AUT certificate of ICC) [o,m]
-   'C108'  EF.C.CA.AUT (AUT certificate of CA) [o,m]
-   'D000'  EF.DM (display message) [-,m]
-
-   The letters in brackets indicate optional or mandatory files: The
-   first for card terminals under full control and the second for
-   "business" card terminals.
-
-   FIXME: Needs a lot more explanation.
-
-*/
-
-
-#include <config.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#ifdef HAVE_OPENSC
-#include <opensc/pkcs15.h>
-#include "scdaemon.h"
-#include <ksba.h>
-
-#include "card-common.h"
-
-static int dinsig_read_cert (CARD card, const char *certidstr,
-                             unsigned char **cert, size_t *ncert);
-
-
-
-/* See card.c for interface description.  Frankly we don't do any real
-   enumeration but just check whether the well know files are
-   available.  */
-static int
-dinsig_enum_keypairs (CARD card, int idx,
-                      unsigned char *keygrip, char **keyid)
-{
-  int rc;
-  unsigned char *buf;
-  size_t buflen;
-  ksba_cert_t cert;
-
-  /* fixme: We should locate the application via the EF(DIR) and not
-     assume a Netkey card */
-  if (!idx)
-    rc = dinsig_read_cert (card, "DINSIG-DF01.C000", &buf, &buflen);
-  else if (idx == 1)
-    rc = dinsig_read_cert (card, "DINSIG-DF01.C200", &buf, &buflen);
-  else
-    rc = -1;
-  if (rc)
-    return rc;
-
-  rc = ksba_cert_new (&cert);
-  if (rc)
-    {
-      xfree (buf);
-      return rc;
-    }
-
-  rc = ksba_cert_init_from_mem (cert, buf, buflen);
-  xfree (buf);
-  if (rc)
-    {
-      log_error ("failed to parse the certificate at idx %d: %s\n",
-                 idx, gpg_strerror (rc));
-      ksba_cert_release (cert);
-      return rc;
-    }
-  if (card_help_get_keygrip (cert, keygrip))
-    {
-      log_error ("failed to calculate the keygrip at index %d\n", idx);
-      ksba_cert_release (cert);
-      return gpg_error (GPG_ERR_CARD);
-    }
-  ksba_cert_release (cert);
-
-  /* return the iD */
-  if (keyid)
-    {
-      *keyid = xtrymalloc (17);
-      if (!*keyid)
-        return gpg_error (gpg_err_code_from_errno (errno));
-      if (!idx)
-        strcpy (*keyid, "DINSIG-DF01.C000");
-      else
-        strcpy (*keyid, "DINSIG-DF01.C200");
-    }
-
-  return 0;
-}
-
-
-\f
-/* See card.c for interface description */
-static int
-dinsig_read_cert (CARD card, const char *certidstr,
-                  unsigned char **cert, size_t *ncert)
-{
-  int rc;
-  struct sc_path path;
-  struct sc_file *file;
-  unsigned char *buf;
-  int buflen;
-
-  if (!strcmp (certidstr, "DINSIG-DF01.C000"))
-    sc_format_path ("3F00DF01C000", &path);
-  else if (!strcmp (certidstr, "DINSIG-DF01.C200"))
-    sc_format_path ("3F00DF01C200", &path);
-  else
-    return gpg_error (GPG_ERR_INV_ID);
-
-  rc = sc_select_file (card->scard, &path, &file);
-  if (rc)
-    {
-      log_error ("sc_select_file failed: %s\n", sc_strerror (rc));
-      return map_sc_err (rc);
-    }
-  if (file->type != SC_FILE_TYPE_WORKING_EF
-      || file->ef_structure != SC_FILE_EF_TRANSPARENT)
-    {
-      log_error ("wrong type or structure of certificate EF\n");
-      sc_file_free (file);
-      return gpg_error (GPG_ERR_CARD);
-    }
-  if (file->size < 20) /* check against a somewhat arbitrary length */
-    {
-      log_error ("certificate EF too short\n");
-      sc_file_free (file);
-      return gpg_error (GPG_ERR_CARD);
-    }
-  buf = xtrymalloc (file->size);
-  if (!buf)
-    {
-      gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
-      sc_file_free (file);
-      return tmperr;
-    }
-
-  rc = sc_read_binary (card->scard, 0, buf, file->size, 0);
-  if (rc >= 0 && rc != file->size)
-    {
-      log_error ("short read on certificate EF\n");
-      sc_file_free (file);
-      xfree (buf);
-      return gpg_error (GPG_ERR_CARD);
-    }
-  sc_file_free (file);
-  if (rc < 0)
-    {
-      log_error ("error reading certificate EF: %s\n", sc_strerror (rc));
-      xfree (buf);
-      return map_sc_err (rc);
-    }
-  buflen = rc;
-
-  /* The object is not a plain certificate but wrapped into id-at
-     userCertificate - fixme: we should check the specs and decided
-     whether libksba should support it */
-  if (buflen > 9 && buf[0] == 0x30 && buf[4] == 6 && buf[5] == 3
-      && buf[6] == 0x55 && buf[7] == 4 && buf[8] == 0x24)
-    {
-      /* We have to strip the padding.  Although this is a good idea
-         anyway, we have to do it due to a KSBA problem; KSBA does not
-         work correct when the buffer is larger than the ASN.1
-         structure and the certificates here are padded with FF.  So
-         as a workaround we look at the outer structure to get the
-         size of the entire thing and adjust the buflen.  We can only
-         do this when there is a 2 byte length field */
-      size_t seqlen;
-      if (buf[1] == 0x82)
-        {
-          seqlen = ((buf[2] << 8) | buf[3]) + 4;
-          if (seqlen < buflen)
-            buflen = seqlen;
-        }
-      memmove (buf, buf+9, buflen-9);
-      buflen -= 9;
-    }
-
-  *cert = buf;
-  *ncert = buflen;
-  return 0;
-}
-
-
-
-
-/* Bind our operations to the card */
-void
-card_dinsig_bind (CARD card)
-{
-  card->fnc.enum_keypairs = dinsig_enum_keypairs;
-  card->fnc.read_cert     = dinsig_read_cert;
-
-}
-#endif /*HAVE_OPENSC*/
diff --git a/scd/card-p15.c b/scd/card-p15.c
deleted file mode 100644 (file)
index 4af4472..0000000
+++ /dev/null
@@ -1,494 +0,0 @@
-/* card-p15.c - PKCS-15 based card access
- *     Copyright (C) 2002 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#ifdef HAVE_OPENSC
-#include <opensc/pkcs15.h>
-
-#include "scdaemon.h"
-#include <ksba.h>
-#include "card-common.h"
-
-
-struct p15private_s {
-  int n_prkey_rsa_objs;
-  struct sc_pkcs15_object *prkey_rsa_objs[32];
-  int n_cert_objs;
-  struct sc_pkcs15_object *cert_objs[32];
-};
-
-
-/* Allocate private data. */
-static int
-init_private_data (CARD card)
-{
-  struct p15private_s *priv;
-  int rc;
-
-  if (card->p15priv)
-    return 0; /* already done. */
-
-  priv = xtrycalloc (1, sizeof *priv);
-  if (!priv)
-    return gpg_error (gpg_err_code_from_errno (errno));
-
-  /* OpenSC (0.7.0) is a bit strange in that the get_objects functions
-     tries to be a bit too clever and implicitly does an enumeration
-     which eventually leads to the fact that every call to this
-     fucntion returns one more macthing object.  The old code in
-     p15_enum_keypairs assume that it would alwyas return the same
-     numer of objects and used this to figure out what the last object
-     enumerated is.  We now do an enum_objects just once and keep it
-     in the private data. */
-  rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_PRKEY_RSA,
-                              priv->prkey_rsa_objs,
-                              DIM (priv->prkey_rsa_objs));
-  if (rc < 0)
-    {
-      log_error ("private keys enumeration failed: %s\n", sc_strerror (rc));
-      xfree (priv);
-      return gpg_error (GPG_ERR_CARD);
-    }
-  priv->n_prkey_rsa_objs = rc;
-
-  /* Read all certificate objects. */
-  rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_CERT_X509,
-                              priv->cert_objs,
-                              DIM (priv->cert_objs));
-  if (rc < 0)
-    {
-      log_error ("private keys enumeration failed: %s\n", sc_strerror (rc));
-      xfree (priv);
-      return gpg_error (GPG_ERR_CARD);
-    }
-  priv->n_cert_objs = rc;
-
-  card->p15priv = priv;
-  return 0;
-}
-
-
-/* Release private data used in this module. */
-void
-p15_release_private_data (CARD card)
-{
-  if (!card->p15priv)
-    return;
-  xfree (card->p15priv);
-  card->p15priv = NULL;
-}
-
-
-
-/* See card.c for interface description */
-static int
-p15_enum_keypairs (CARD card, int idx,
-                   unsigned char *keygrip, char **keyid)
-{
-  int rc;
-  struct p15private_s *priv;
-  struct sc_pkcs15_object *tmpobj;
-  int nobjs;
-  struct sc_pkcs15_prkey_info *pinfo;
-  struct sc_pkcs15_cert_info *certinfo;
-  struct sc_pkcs15_cert      *certder;
-  ksba_cert_t cert;
-
-  rc = init_private_data (card);
-  if (rc)
-      return rc;
-  priv = card->p15priv;
-  nobjs = priv->n_prkey_rsa_objs;
-  rc = 0;
-  if (idx >= nobjs)
-    return -1;
-  pinfo = priv->prkey_rsa_objs[idx]->data;
-
-  /* now we need to read the certificate so that we can calculate the
-     keygrip */
-  rc = sc_pkcs15_find_cert_by_id (card->p15card, &pinfo->id, &tmpobj);
-  if (rc)
-    {
-      log_info ("certificate for private key %d not found: %s\n",
-                idx, sc_strerror (rc));
-      /* note, that we return the ID anyway */
-      rc = gpg_error (GPG_ERR_MISSING_CERT);
-      goto return_keyid;
-    }
-  certinfo = tmpobj->data;
-  rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder);
-  if (rc)
-    {
-      log_info ("failed to read certificate for private key %d: %s\n",
-                idx, sc_strerror (rc));
-      return gpg_error (GPG_ERR_CARD);
-    }
-
-  rc = ksba_cert_new (&cert);
-  if (rc)
-    {
-      sc_pkcs15_free_certificate (certder);
-      return rc;
-    }
-  rc = ksba_cert_init_from_mem (cert, certder->data, certder->data_len);
-  sc_pkcs15_free_certificate (certder);
-  if (rc)
-    {
-      log_error ("failed to parse the certificate for private key %d: %s\n",
-                 idx, gpg_strerror (rc));
-      ksba_cert_release (cert);
-      return rc;
-    }
-  if (card_help_get_keygrip (cert, keygrip))
-    {
-      log_error ("failed to calculate the keygrip of private key %d\n", idx);
-      ksba_cert_release (cert);
-      return gpg_error (GPG_ERR_CARD);
-    }
-  ksba_cert_release (cert);
-
-  rc = 0;
- return_keyid:
-  if (keyid)
-    {
-      char *p;
-
-      *keyid = p = xtrymalloc (9+pinfo->id.len*2+1);
-      if (!*keyid)
-        return gpg_error (gpg_err_code_from_errno (errno));
-      p = stpcpy (p, "P15-5015.");
-      bin2hex (pinfo->id.value, pinfo->id.len, p);
-    }
-
-  return rc;
-}
-
-/* See card.c for interface description */
-static int
-p15_enum_certs (CARD card, int idx, char **certid, int *type)
-{
-  int rc;
-  struct p15private_s *priv;
-  struct sc_pkcs15_object *obj;
-  struct sc_pkcs15_cert_info *cinfo;
-  int nobjs;
-
-  rc = init_private_data (card);
-  if (rc)
-      return rc;
-  priv = card->p15priv;
-  nobjs = priv->n_cert_objs;
-  rc = 0;
-  if (idx >= nobjs)
-    return -1;
-  obj =  priv->cert_objs[idx];
-  cinfo = obj->data;
-
-  if (certid)
-    {
-      char *p;
-      int i;
-
-      *certid = p = xtrymalloc (9+cinfo->id.len*2+1);
-      if (!*certid)
-        return gpg_error (gpg_err_code_from_errno (errno));
-      p = stpcpy (p, "P15-5015.");
-      bin2hex (cinfo->id.value, cinfo->id.len, p);
-    }
-  if (type)
-    {
-      if (!obj->df)
-        *type = 0; /* unknown */
-      else if (obj->df->type == SC_PKCS15_CDF)
-        *type = 100;
-      else if (obj->df->type == SC_PKCS15_CDF_TRUSTED)
-        *type = 101;
-      else if (obj->df->type == SC_PKCS15_CDF_USEFUL)
-        *type = 102;
-      else
-        *type = 0; /* error -> unknown */
-    }
-
-  return rc;
-}
-
-
-\f
-static int
-idstr_to_id (const char *idstr, struct sc_pkcs15_id *id)
-{
-  const char *s;
-  int n;
-
-  /* For now we only support the standard DF */
-  if (strncmp (idstr, "P15-5015.", 9) )
-    return gpg_error (GPG_ERR_INV_ID);
-  for (s=idstr+9, n=0; hexdigitp (s); s++, n++)
-    ;
-  if (*s || (n&1))
-    return gpg_error (GPG_ERR_INV_ID); /*invalid or odd number of digits*/
-  n /= 2;
-  if (!n || n > SC_PKCS15_MAX_ID_SIZE)
-    return gpg_error (GPG_ERR_INV_ID); /* empty or too large */
-  for (s=idstr+9, n=0; *s; s += 2, n++)
-    id->value[n] = xtoi_2 (s);
-  id->len = n;
-  return 0;
-}
-
-
-/* See card.c for interface description */
-static int
-p15_read_cert (CARD card, const char *certidstr,
-               unsigned char **cert, size_t *ncert)
-{
-  struct sc_pkcs15_object *tmpobj;
-  struct sc_pkcs15_id certid;
-  struct sc_pkcs15_cert_info *certinfo;
-  struct sc_pkcs15_cert      *certder;
-  int rc;
-
-  if (!card || !certidstr || !cert || !ncert)
-    return gpg_error (GPG_ERR_INV_VALUE);
-  if (!card->p15card)
-    return gpg_error (GPG_ERR_NO_PKCS15_APP);
-
-  rc = idstr_to_id (certidstr, &certid);
-  if (rc)
-    return rc;
-
-  rc = sc_pkcs15_find_cert_by_id (card->p15card, &certid, &tmpobj);
-  if (rc)
-    {
-      log_info ("certificate '%s' not found: %s\n",
-                certidstr, sc_strerror (rc));
-      return -1;
-    }
-  certinfo = tmpobj->data;
-  rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder);
-  if (rc)
-    {
-      log_info ("failed to read certificate '%s': %s\n",
-                certidstr, sc_strerror (rc));
-      return gpg_error (GPG_ERR_CARD);
-    }
-
-  *cert = xtrymalloc (certder->data_len);
-  if (!*cert)
-    {
-      gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
-      sc_pkcs15_free_certificate (certder);
-      return tmperr;
-    }
-  memcpy (*cert, certder->data, certder->data_len);
-  *ncert = certder->data_len;
-  sc_pkcs15_free_certificate (certder);
-  return 0;
-}
-
-
-
-
-\f
-static int
-p15_prepare_key (CARD card, const char *keyidstr,
-                 int (pincb)(void*, const char *, char **),
-                 void *pincb_arg, struct sc_pkcs15_object **r_keyobj)
-{
-  struct sc_pkcs15_id keyid;
-  struct sc_pkcs15_pin_info *pin;
-  struct sc_pkcs15_object *keyobj, *pinobj;
-  char *pinvalue;
-  int rc;
-
-  rc = idstr_to_id (keyidstr, &keyid);
-  if (rc)
-    return rc;
-
-  rc = sc_pkcs15_find_prkey_by_id (card->p15card, &keyid, &keyobj);
-  if (rc < 0)
-    {
-      log_error ("private key not found: %s\n", sc_strerror(rc));
-      return gpg_error (GPG_ERR_NO_SECKEY);
-    }
-
-  rc = sc_pkcs15_find_pin_by_auth_id (card->p15card,
-                                      &keyobj->auth_id, &pinobj);
-  if (rc)
-    {
-      log_error ("failed to find PIN by auth ID: %s\n", sc_strerror (rc));
-      return gpg_error (GPG_ERR_BAD_PIN_METHOD);
-    }
-  pin = pinobj->data;
-
-  /* Fixme: pack this into a verification loop */
-  /* Fixme: we might want to pass pin->min_length and
-     pin->stored_length */
-  rc = pincb (pincb_arg, pinobj->label, &pinvalue);
-  if (rc)
-    {
-      log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
-      return rc;
-    }
-
-  rc = sc_pkcs15_verify_pin (card->p15card, pin,
-                             pinvalue, strlen (pinvalue));
-  xfree (pinvalue);
-  if (rc)
-    {
-      log_info ("PIN verification failed: %s\n", sc_strerror (rc));
-      return gpg_error (GPG_ERR_BAD_PIN);
-    }
-
-  /* fixme: check wheter we need to release KEYOBJ in case of an error */
-  *r_keyobj = keyobj;
-  return 0;
-}
-
-
-/* See card.c for interface description */
-static int
-p15_sign (CARD card, const char *keyidstr, int hashalgo,
-          int (pincb)(void*, const char *, char **),
-          void *pincb_arg,
-          const void *indata, size_t indatalen,
-          unsigned char **outdata, size_t *outdatalen )
-{
-  unsigned int cryptflags;
-  struct sc_pkcs15_object *keyobj;
-  int rc;
-  unsigned char *outbuf = NULL;
-  size_t outbuflen;
-
-  if (hashalgo != GCRY_MD_SHA1)
-    return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
-
-  rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj);
-  if (rc)
-    return rc;
-
-  cryptflags = SC_ALGORITHM_RSA_PAD_PKCS1;
-
-  outbuflen = 1024;
-  outbuf = xtrymalloc (outbuflen);
-  if (!outbuf)
-    return gpg_error (gpg_err_code_from_errno (errno));
-
-  rc = sc_pkcs15_compute_signature (card->p15card, keyobj,
-                                    cryptflags,
-                                    indata, indatalen,
-                                    outbuf, outbuflen );
-  if (rc < 0)
-    {
-      log_error ("failed to create signature: %s\n", sc_strerror (rc));
-      rc = gpg_error (GPG_ERR_CARD);
-    }
-  else
-    {
-      *outdatalen = rc;
-      *outdata = outbuf;
-      outbuf = NULL;
-      rc = 0;
-    }
-
-  xfree (outbuf);
-  return rc;
-}
-
-
-/* See card.c for description */
-static int
-p15_decipher (CARD card, const char *keyidstr,
-              int (pincb)(void*, const char *, char **),
-              void *pincb_arg,
-              const void *indata, size_t indatalen,
-              unsigned char **outdata, size_t *outdatalen )
-{
-  struct sc_pkcs15_object *keyobj;
-  int rc;
-  unsigned char *outbuf = NULL;
-  size_t outbuflen;
-
-  rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj);
-  if (rc)
-    return rc;
-
-  if (card && card->scard && card->scard->driver
-      && !strcasecmp (card->scard->driver->short_name, "tcos"))
-    {
-      /* very ugly hack to force the use of a local key.  We need this
-         until we have fixed the initialization code for TCOS cards */
-      struct sc_pkcs15_prkey_info *prkey = keyobj->data;
-      if ( !(prkey->key_reference & 0x80))
-        {
-          prkey->key_reference |= 0x80;
-          log_debug ("using TCOS hack to force the use of local keys\n");
-        }
-      if (*keyidstr && keyidstr[strlen(keyidstr)-1] == '6')
-        {
-          prkey->key_reference |= 1;
-          log_debug ("warning: using even more TCOS hacks\n");
-        }
-    }
-
-  outbuflen = indatalen < 256? 256 : indatalen;
-  outbuf = xtrymalloc (outbuflen);
-  if (!outbuf)
-    return gpg_error (gpg_err_code_from_errno (errno));
-
-  rc = sc_pkcs15_decipher (card->p15card, keyobj,
-                           0,
-                           indata, indatalen,
-                           outbuf, outbuflen);
-  if (rc < 0)
-    {
-      log_error ("failed to decipher the data: %s\n", sc_strerror (rc));
-      rc = gpg_error (GPG_ERR_CARD);
-    }
-  else
-    {
-      *outdatalen = rc;
-      *outdata = outbuf;
-      outbuf = NULL;
-      rc = 0;
-    }
-
-  xfree (outbuf);
-  return rc;
-}
-
-
-
-/* Bind our operations to the card */
-void
-card_p15_bind (CARD card)
-{
-  card->fnc.enum_keypairs = p15_enum_keypairs;
-  card->fnc.enum_certs    = p15_enum_certs;
-  card->fnc.read_cert     = p15_read_cert;
-  card->fnc.sign          = p15_sign;
-  card->fnc.decipher      = p15_decipher;
-}
-#endif /*HAVE_OPENSC*/
diff --git a/scd/card.c b/scd/card.c
deleted file mode 100644 (file)
index a582c50..0000000
+++ /dev/null
@@ -1,568 +0,0 @@
-/* card.c - SCdaemon card functions
- *     Copyright (C) 2002 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#ifdef HAVE_OPENSC
-#include <opensc/pkcs15.h>
-#endif
-
-#include "scdaemon.h"
-#include <ksba.h>
-
-#include "card-common.h"
-
-/* Map the SC error codes to the GNUPG ones */
-gpg_error_t
-map_sc_err (int rc)
-{
-  gpg_err_code_t e;
-
-  switch (rc)
-    {
-    case 0: e = 0; break;
-#ifdef HAVE_OPENSC
-    case SC_ERROR_NOT_SUPPORTED:         e = GPG_ERR_NOT_SUPPORTED; break;
-    case SC_ERROR_PKCS15_APP_NOT_FOUND:  e = GPG_ERR_NO_PKCS15_APP; break;
-    case SC_ERROR_OUT_OF_MEMORY:         e = GPG_ERR_ENOMEM; break;
-    case SC_ERROR_CARD_NOT_PRESENT:      e = GPG_ERR_CARD_NOT_PRESENT; break;
-    case SC_ERROR_CARD_REMOVED:          e = GPG_ERR_CARD_REMOVED; break;
-    case SC_ERROR_INVALID_CARD:          e = GPG_ERR_INV_CARD; break;
-#endif
-    default: e = GPG_ERR_CARD; break;
-    }
-  /* It does not make much sense to further distingusih the error
-     source between OpenSC and SCD.  Thus we use SCD as source
-     here. */
-  return gpg_err_make (GPG_ERR_SOURCE_SCD, e);
-}
-
-/* Get the keygrip from CERT, return 0 on success */
-int
-card_help_get_keygrip (ksba_cert_t cert, unsigned char *array)
-{
-  gcry_sexp_t s_pkey;
-  int rc;
-  ksba_sexp_t p;
-  size_t n;
-
-  p = ksba_cert_get_public_key (cert);
-  if (!p)
-    return -1; /* oops */
-  n = gcry_sexp_canon_len (p, 0, NULL, NULL);
-  if (!n)
-    return -1; /* libksba did not return a proper S-expression */
-  rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n);
-  xfree (p);
-  if (rc)
-    return -1; /* can't parse that S-expression */
-  array = gcry_pk_get_keygrip (s_pkey, array);
-  gcry_sexp_release (s_pkey);
-  if (!array)
-    return -1; /* failed to calculate the keygrip */
-  return 0;
-}
-
-
-
-
-
-
-\f
-/* Create a new context for the card and figures out some basic
-   information of the card.  Detects whether a PKCS_15 application is
-   stored.
-
-   Common errors: GPG_ERR_CARD_NOT_PRESENT */
-int
-card_open (CARD *rcard)
-{
-#ifdef HAVE_OPENSC
-  CARD card;
-  int rc;
-
-  if (opt.disable_opensc)
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  card = xtrycalloc (1, sizeof *card);
-  if (!card)
-    return gpg_error (gpg_err_code_from_errno (errno));
-  card->reader = 0;
-
-  rc = sc_establish_context (&card->ctx, "scdaemon");
-  if (rc)
-    {
-      log_error ("failed to establish SC context: %s\n", sc_strerror (rc));
-      rc = map_sc_err (rc);
-      goto leave;
-    }
-  if (card->reader >= card->ctx->reader_count)
-    {
-      log_error ("no card reader available\n");
-      rc = gpg_error (GPG_ERR_CARD);
-      goto leave;
-    }
-  card->ctx->error_file = log_get_stream ();
-  card->ctx->debug = opt.debug_sc;
-  card->ctx->debug_file = log_get_stream ();
-
-  if (sc_detect_card_presence (card->ctx->reader[card->reader], 0) != 1)
-    {
-      rc = gpg_error (GPG_ERR_CARD_NOT_PRESENT);
-      goto leave;
-    }
-
-  rc = sc_connect_card (card->ctx->reader[card->reader], 0, &card->scard);
-  if (rc)
-    {
-      log_error ("failed to connect card in reader %d: %s\n",
-                 card->reader, sc_strerror (rc));
-      rc = map_sc_err (rc);
-      goto leave;
-    }
-  if (opt.verbose)
-    log_info ("connected to card in reader %d using driver '%s'\n",
-              card->reader, card->scard->driver->name);
-
-  rc = sc_lock (card->scard);
-  if (rc)
-    {
-      log_error ("can't lock card in reader %d: %s\n",
-                 card->reader, sc_strerror (rc));
-      rc = map_sc_err (rc);
-      goto leave;
-    }
-
-
- leave:
-  if (rc)
-    card_close (card);
-  else
-    *rcard = card;
-
-  return rc;
-#else
-  return gpg_error (GPG_ERR_NOT_SUPPORTED);
-#endif
-}
-
-
-/* Close a card and release all resources */
-void
-card_close (CARD card)
-{
-  if (card)
-    {
-#ifdef HAVE_OPENSC
-      if (card->p15card)
-        {
-          sc_pkcs15_unbind (card->p15card);
-          card->p15card = NULL;
-        }
-      if (card->p15priv)
-        p15_release_private_data (card);
-      if (card->scard)
-        {
-          sc_unlock (card->scard);
-          sc_disconnect_card (card->scard, 0);
-          card->scard = NULL;
-       }
-      if (card->ctx)
-        {
-          sc_release_context (card->ctx);
-          card->ctx = NULL;
-        }
-#endif
-      xfree (card);
-    }
-}
-
-/* Locate a simple TLV encoded data object in BUFFER of LENGTH and
-   return a pointer to value as well as its length in NBYTES.  Return
-   NULL if it was not found.  Note, that the function does not check
-   whether the value fits into the provided buffer. */
-#ifdef HAVE_OPENSC
-static const char *
-find_simple_tlv (const unsigned char *buffer, size_t length,
-                 int tag, size_t *nbytes)
-{
-  const char *s = buffer;
-  size_t n = length;
-  size_t len;
-
-  for (;;)
-    {
-      buffer = s;
-      if (n < 2)
-        return NULL; /* buffer too short for tag and length. */
-      len = s[1];
-      s += 2; n -= 2;
-      if (len == 255)
-        {
-          if (n < 2)
-            return NULL; /* we expected 2 more bytes with the length. */
-          len = (s[0] << 8) | s[1];
-          s += 2; n -= 2;
-        }
-      if (*buffer == tag)
-        {
-          *nbytes = len;
-          return s;
-        }
-      if (len > n)
-        return NULL; /* buffer too short to skip to the next tag. */
-      s += len; n -= len;
-    }
-}
-#endif /*HAVE_OPENSC*/
-
-/* Find the ICC Serial Number within the provided BUFFER of LENGTH
-   (which should contain the GDO file) and return it as a hex encoded
-   string and allocated string in SERIAL.  Return an error code when
-   the ICCSN was not found. */
-#ifdef HAVE_OPENSC
-static int
-find_iccsn (const unsigned char *buffer, size_t length, char **serial)
-{
-  size_t n;
-  const unsigned char *s;
-  char *p;
-
-  s = find_simple_tlv (buffer, length, 0x5A, &n);
-  if (!s)
-    return gpg_error (GPG_ERR_CARD);
-  length -= s - buffer;
-  if (n > length)
-    {
-      /* Oops, it does not fit into the buffer.  This is an invalid
-         encoding (or the buffer is too short.  However, I have some
-         test cards with such an invalid encoding and therefore I use
-         this ugly workaround to return something I can further
-         experiment with. */
-      if (n == 0x0D && length+1 == n)
-        {
-          log_debug ("enabling BMI testcard workaround\n");
-          n--;
-        }
-      else
-        return gpg_error (GPG_ERR_CARD); /* Bad encoding; does
-                                           not fit into buffer. */
-    }
-  if (!n)
-    return gpg_error (GPG_ERR_CARD); /* Well, that is too short. */
-
-  *serial = p = xtrymalloc (2*n+1);
-  if (!*serial)
-    return gpg_error (gpg_err_code_from_errno (errno));
-  for (; n; n--, p += 2, s++)
-    sprintf (p, "%02X", *s);
-  *p = 0;
-  return 0;
-}
-#endif /*HAVE_OPENSC*/
-
-/* Retrieve the serial number and the time of the last update of the
-   card.  The serial number is returned as a malloced string (hex
-   encoded) in SERIAL and the time of update is returned in STAMP.
-   If no update time is available the returned value is 0.  The serial
-   is mandatory for a PKCS_15 application and an error will be
-   returned if this value is not availbale.  For non-PKCS-15 cards a
-   serial number is constructed by other means. Caller must free
-   SERIAL unless the function returns an error. */
-int
-card_get_serial_and_stamp (CARD card, char **serial, time_t *stamp)
-{
-#ifdef HAVE_OPENSC
-  int rc;
-  struct sc_path path;
-  struct sc_file *file;
-  unsigned char buf[256];
-  int buflen;
-#endif
-
-  if (!card || !serial || !stamp)
-    return gpg_error (GPG_ERR_INV_VALUE);
-
-  *serial = NULL;
-  *stamp = 0; /* not available */
-
-#ifdef HAVE_OPENSC
-  if (!card->fnc.initialized)
-    {
-      card->fnc.initialized = 1;
-      /* The first use of this card tries to figure out the type of the card
-         and sets up the function pointers. */
-      rc = sc_pkcs15_bind (card->scard, &card->p15card);
-      if (rc)
-        {
-          if (rc != SC_ERROR_PKCS15_APP_NOT_FOUND)
-            log_error ("binding of existing PKCS-15 failed in reader %d: %s\n",
-                       card->reader, sc_strerror (rc));
-          card->p15card = NULL;
-          rc = 0;
-        }
-      if (card->p15card)
-        card_p15_bind (card);
-      card->fnc.initialized = 1;
-    }
-
-
-  /* We should lookup the iso 7812-1 and 8583-3 - argh ISO
-     practice is suppressing innovation - IETF rules!  So we
-     always get the serialnumber from the 2F02 GDO file.  */
-  /* FIXME: in case we can't parse the 2F02 EF and we have a P15 card,
-     we should get the serial number from the respective P15 file */
-  sc_format_path ("3F002F02", &path);
-  rc = sc_select_file (card->scard, &path, &file);
-  if (rc)
-    {
-      log_error ("sc_select_file failed: %s\n", sc_strerror (rc));
-      return gpg_error (GPG_ERR_CARD);
-    }
-  if (file->type != SC_FILE_TYPE_WORKING_EF
-      || file->ef_structure != SC_FILE_EF_TRANSPARENT)
-    {
-      log_error ("wrong type or structure of GDO file\n");
-      sc_file_free (file);
-      return gpg_error (GPG_ERR_CARD);
-    }
-
-  if (!file->size || file->size >= DIM(buf) )
-    { /* FIXME: Use a real parser */
-      log_error ("unsupported size of GDO file (%d)\n", file->size);
-      sc_file_free (file);
-      return gpg_error (GPG_ERR_CARD);
-    }
-  buflen = file->size;
-
-  rc = sc_read_binary (card->scard, 0, buf, buflen, 0);
-  sc_file_free (file);
-  if (rc < 0)
-    {
-      log_error ("error reading GDO file: %s\n", sc_strerror (rc));
-      return gpg_error (GPG_ERR_CARD);
-    }
-  if (rc != buflen)
-    {
-      log_error ("short read on GDO file\n");
-      return gpg_error (GPG_ERR_CARD);
-    }
-
-  rc = find_iccsn (buf, buflen, serial);
-  if (gpg_err_code (rc) == GPG_ERR_CARD)
-    log_error ("invalid structure of GDO file\n");
-  if (!rc && card->p15card && !strcmp (*serial, "D27600000000000000000000"))
-    { /* This is a German card with a silly serial number.  Try to get
-         the serial number from the EF(TokenInfo). We indicate such a
-         serial number by the using the prefix: "FF0100". */
-      const char *efser = card->p15card->serial_number;
-      char *p;
-
-      if (!efser)
-        efser = "";
-
-      xfree (*serial);
-      *serial = NULL;
-      p = xtrymalloc (strlen (efser) + 7);
-      if (!p)
-          rc = gpg_error (gpg_err_code_from_errno (errno));
-      else
-        {
-          strcpy (p, "FF0100");
-          strcpy (p+6, efser);
-          *serial = p;
-        }
-    }
-  else if (!rc && **serial == 'F' && (*serial)[1] == 'F')
-    { /* The serial number starts with our special prefix.  This
-         requires that we put our default prefix "FF0000" in front. */
-      char *p = xtrymalloc (strlen (*serial) + 7);
-      if (!p)
-        {
-          xfree (*serial);
-          *serial = NULL;
-          rc = gpg_error (gpg_err_code_from_errno (errno));
-        }
-      else
-        {
-          strcpy (p, "FF0000");
-          strcpy (p+6, *serial);
-          xfree (*serial);
-          *serial = p;
-        }
-    }
-  return rc;
-#else
-  return gpg_error (GPG_ERR_NOT_SUPPORTED);
-#endif
-}
-
-
-/* Enumerate all keypairs on the card and return the Keygrip as well
-   as the internal identification of the key.  KEYGRIP must be a
-   caller provided buffer with a size of 20 bytes which will receive
-   the KEYGRIP of the keypair.  If KEYID is not NULL, it returns the
-   ID field of the key in allocated memory; this is a string without
-   spaces.  The function returns -1 when all keys have been
-   enumerated.  Note that the error GPG_ERR_MISSING_CERTIFICATE may be
-   returned if there is just the private key but no public key (ie.e a
-   certificate) available.  Applications might want to continue
-   enumerating after this error.*/
-int
-card_enum_keypairs (CARD card, int idx,
-                    unsigned char *keygrip,
-                    char **keyid)
-{
-  int rc;
-
-  if (keyid)
-    *keyid = NULL;
-
-  if (!card || !keygrip)
-    return gpg_error (GPG_ERR_INV_VALUE);
-  if (idx < 0)
-    return gpg_error (GPG_ERR_INV_INDEX);
-  if (!card->fnc.initialized)
-    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
-  if (!card->fnc.enum_keypairs)
-    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
-  rc = card->fnc.enum_keypairs (card, idx, keygrip, keyid);
-  if (opt.verbose)
-    log_info ("card operation enum_keypairs result: %s\n",
-              gpg_strerror (rc));
-  return rc;
-}
-
-
-/* Enumerate all trusted certificates available on the card, return
-   their ID in CERT and the type in CERTTYPE.  Types of certificates
-   are:
-      0   := Unknown
-      100 := Regular X.509 cert
-      101 := Trusted X.509 cert
-      102 := Useful X.509 cert
-      110 := Root CA cert (DINSIG)
- */
-int
-card_enum_certs (CARD card, int idx, char **certid, int *certtype)
-{
-  int rc;
-
-  if (certid)
-    *certid = NULL;
-
-  if (!card)
-    return gpg_error (GPG_ERR_INV_VALUE);
-  if (idx < 0)
-    return gpg_error (GPG_ERR_INV_INDEX);
-  if (!card->fnc.initialized)
-    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
-  if (!card->fnc.enum_certs)
-    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
-  rc = card->fnc.enum_certs (card, idx, certid, certtype);
-  if (opt.verbose)
-    log_info ("card operation enum_certs result: %s\n",
-              gpg_strerror (rc));
-  return rc;
-}
-
-
-
-/* Read the certificate identified by CERTIDSTR which is the
-   hexadecimal encoded ID of the certificate, prefixed with the string
-   "3F005015.". The certificate is return in DER encoded form in CERT
-   and NCERT. */
-int
-card_read_cert (CARD card, const char *certidstr,
-                unsigned char **cert, size_t *ncert)
-{
-  int rc;
-
-  if (!card || !certidstr || !cert || !ncert)
-    return gpg_error (GPG_ERR_INV_VALUE);
-  if (!card->fnc.initialized)
-    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
-  if (!card->fnc.read_cert)
-    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
-  rc = card->fnc.read_cert (card, certidstr, cert, ncert);
-  if (opt.verbose)
-    log_info ("card operation read_cert result: %s\n", gpg_strerror (rc));
-  return rc;
-}
-
-
-/* Create the signature and return the allocated result in OUTDATA.
-   If a PIN is required the PINCB will be used to ask for the PIN; it
-   should return the PIN in an allocated buffer and put it into PIN.  */
-int
-card_sign (CARD card, const char *keyidstr, int hashalgo,
-           int (pincb)(void*, const char *, char **),
-           void *pincb_arg,
-           const void *indata, size_t indatalen,
-           unsigned char **outdata, size_t *outdatalen )
-{
-  int rc;
-
-  if (!card || !indata || !indatalen || !outdata || !outdatalen || !pincb)
-    return gpg_error (GPG_ERR_INV_VALUE);
-  if (!card->fnc.initialized)
-    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
-  if (!card->fnc.sign)
-    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
-  rc =  card->fnc.sign (card, keyidstr, hashalgo,
-                        pincb, pincb_arg,
-                        indata, indatalen,
-                        outdata, outdatalen);
-  if (opt.verbose)
-    log_info ("card operation sign result: %s\n", gpg_strerror (rc));
-  return rc;
-}
-
-
-/* Create the signature and return the allocated result in OUTDATA.
-   If a PIN is required the PINCB will be used to ask for the PIN; it
-   should return the PIN in an allocated buffer and put it into PIN.  */
-int
-card_decipher (CARD card, const char *keyidstr,
-               int (pincb)(void*, const char *, char **),
-               void *pincb_arg,
-               const void *indata, size_t indatalen,
-               unsigned char **outdata, size_t *outdatalen )
-{
-  int rc;
-
-  if (!card || !indata || !indatalen || !outdata || !outdatalen || !pincb)
-    return gpg_error (GPG_ERR_INV_VALUE);
-  if (!card->fnc.initialized)
-    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
-  if (!card->fnc.decipher)
-    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
-  rc =  card->fnc.decipher (card, keyidstr,
-                            pincb, pincb_arg,
-                            indata, indatalen,
-                            outdata, outdatalen);
-  if (opt.verbose)
-    log_info ("card operation decipher result: %s\n", gpg_strerror (rc));
-  return rc;
-}
diff --git a/scd/pcsc-wrapper.c b/scd/pcsc-wrapper.c
deleted file mode 100644 (file)
index 843603a..0000000
+++ /dev/null
@@ -1,911 +0,0 @@
-/* pcsc-wrapper.c - Wrapper for accessing the PC/SC service
- *     Copyright (C) 2003, 2004 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
-  This wrapper is required to handle problems with the libpscslite
-  library.  That library assumes that pthreads are used and fails
-  badly if one tries to use it with a process using Pth.  Note that
-  the wrapper is not required if nPth is used.
-
-  The operation model is pretty simple: It reads requests from stdin
-  and returns the answer on stdout.  There is no direct mapping to the
-  pcsc interface but to a higher level one which resembles the code
-  used in scdaemon (apdu.c) when not using Pth or while running under
-  Windows.
-
-  The interface is binary consisting of a command tag and the length
-  of the parameter list.  The calling process needs to pass the
-  version number of the interface on the command line to make sure
-  that both agree on the same interface.  For each port a separate
-  instance of this process needs to be started.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <assert.h>
-#include <dlfcn.h>
-
-
-#define PGM "pcsc-wrapper"
-
-/* Allow for a standalone build. */
-#ifdef VERSION
-#define MYVERSION_LINE PGM " ("GNUPG_NAME") " VERSION
-#define BUGREPORT_LINE "\nReport bugs to <bug-gnupg@gnu.org>.\n"
-#else
-#define MYVERSION_LINE PGM
-#define BUGREPORT_LINE ""
-#endif
-
-#define DEFAULT_PCSC_DRIVER "libpcsclite.so"
-
-
-static int verbose;
-
-#if defined(__APPLE__) || defined(_WIN32) || defined(__CYGWIN__)
-typedef unsigned int pcsc_dword_t;
-#else
-typedef unsigned long pcsc_dword_t;
-#endif
-
-
-/* PC/SC constants and function pointer. */
-#define PCSC_SCOPE_USER      0
-#define PCSC_SCOPE_TERMINAL  1
-#define PCSC_SCOPE_SYSTEM    2
-#define PCSC_SCOPE_GLOBAL    3
-
-#define PCSC_PROTOCOL_T0     1
-#define PCSC_PROTOCOL_T1     2
-#define PCSC_PROTOCOL_RAW    4
-
-#define PCSC_SHARE_EXCLUSIVE 1
-#define PCSC_SHARE_SHARED    2
-#define PCSC_SHARE_DIRECT    3
-
-#define PCSC_LEAVE_CARD      0
-#define PCSC_RESET_CARD      1
-#define PCSC_UNPOWER_CARD    2
-#define PCSC_EJECT_CARD      3
-
-#define PCSC_UNKNOWN    0x0001
-#define PCSC_ABSENT     0x0002  /* Card is absent.  */
-#define PCSC_PRESENT    0x0004  /* Card is present.  */
-#define PCSC_SWALLOWED  0x0008  /* Card is present and electrical connected. */
-#define PCSC_POWERED    0x0010  /* Card is powered.  */
-#define PCSC_NEGOTIABLE 0x0020  /* Card is awaiting PTS.  */
-#define PCSC_SPECIFIC   0x0040  /* Card is ready for use.  */
-
-#define PCSC_STATE_UNAWARE     0x0000  /* Want status.  */
-#define PCSC_STATE_IGNORE      0x0001  /* Ignore this reader.  */
-#define PCSC_STATE_CHANGED     0x0002  /* State has changed.  */
-#define PCSC_STATE_UNKNOWN     0x0004  /* Reader unknown.  */
-#define PCSC_STATE_UNAVAILABLE 0x0008  /* Status unavailable.  */
-#define PCSC_STATE_EMPTY       0x0010  /* Card removed.  */
-#define PCSC_STATE_PRESENT     0x0020  /* Card inserted.  */
-#define PCSC_STATE_ATRMATCH    0x0040  /* ATR matches card. */
-#define PCSC_STATE_EXCLUSIVE   0x0080  /* Exclusive Mode.  */
-#define PCSC_STATE_INUSE       0x0100  /* Shared mode.  */
-#define PCSC_STATE_MUTE               0x0200  /* Unresponsive card.  */
-
-struct pcsc_io_request_s {
-  unsigned long protocol;
-  unsigned long pci_len;
-};
-
-typedef struct pcsc_io_request_s *pcsc_io_request_t;
-
-#ifdef __APPLE__
-#pragma pack(1)
-#endif
-
-struct pcsc_readerstate_s
-{
-  const char *reader;
-  void *user_data;
-  pcsc_dword_t current_state;
-  pcsc_dword_t event_state;
-  pcsc_dword_t atrlen;
-  unsigned char atr[33];
-};
-
-#ifdef __APPLE__
-#pragma pack()
-#endif
-
-typedef struct pcsc_readerstate_s *pcsc_readerstate_t;
-
-
-static int driver_is_open;     /* True if the PC/SC driver has been
-                                  initialzied and is ready for
-                                  operations.  The following variables
-                                  are then valid. */
-static long pcsc_context;  /* The current PC/CS context. */
-static char *current_rdrname;
-static long pcsc_card;
-static pcsc_dword_t pcsc_protocol;
-static unsigned char current_atr[33];
-static size_t current_atrlen;
-
-long (* pcsc_establish_context) (pcsc_dword_t scope,
-                                 const void *reserved1,
-                                 const void *reserved2,
-                                 long *r_context);
-long (* pcsc_release_context) (long context);
-long (* pcsc_list_readers) (long context,
-                            const char *groups,
-                            char *readers, pcsc_dword_t *readerslen);
-long (* pcsc_get_status_change) (long context,
-                                 pcsc_dword_t timeout,
-                                 pcsc_readerstate_t readerstates,
-                                 pcsc_dword_t nreaderstates);
-long (* pcsc_connect) (long context,
-                       const char *reader,
-                       pcsc_dword_t share_mode,
-                       pcsc_dword_t preferred_protocols,
-                       long *r_card,
-                       pcsc_dword_t *r_active_protocol);
-long (* pcsc_reconnect) (long card,
-                         pcsc_dword_t share_mode,
-                         pcsc_dword_t preferred_protocols,
-                         pcsc_dword_t initialization,
-                         pcsc_dword_t *r_active_protocol);
-long (* pcsc_disconnect) (long card,
-                          pcsc_dword_t disposition);
-long (* pcsc_status) (long card,
-                      char *reader, pcsc_dword_t *readerlen,
-                      pcsc_dword_t *r_state,
-                      pcsc_dword_t *r_protocol,
-                      unsigned char *atr, pcsc_dword_t *atrlen);
-long (* pcsc_begin_transaction) (long card);
-long (* pcsc_end_transaction) (long card,
-                               pcsc_dword_t disposition);
-long (* pcsc_transmit) (long card,
-                        const pcsc_io_request_t send_pci,
-                        const unsigned char *send_buffer,
-                        pcsc_dword_t send_len,
-                        pcsc_io_request_t recv_pci,
-                        unsigned char *recv_buffer,
-                        pcsc_dword_t *recv_len);
-long (* pcsc_set_timeout) (long context,
-                           pcsc_dword_t timeout);
-long (* pcsc_control) (long card,
-                       pcsc_dword_t control_code,
-                       const void *send_buffer,
-                       pcsc_dword_t send_len,
-                       void *recv_buffer,
-                       pcsc_dword_t recv_len,
-                       pcsc_dword_t *bytes_returned);
-
-
-
-static void
-bad_request (const char *type)
-{
-  fprintf (stderr, PGM ": bad '%s' request\n", type);
-  exit (1);
-}
-
-static void
-request_failed (int err)
-{
-  if (!err)
-    err = -1;
-
-  putchar (0x81); /* Simple error/success response. */
-
-  putchar (0);
-  putchar (0);
-  putchar (0);
-  putchar (4);
-
-  putchar ((err >> 24) & 0xff);
-  putchar ((err >> 16) & 0xff);
-  putchar ((err >>  8) & 0xff);
-  putchar ((err      ) & 0xff);
-
-  fflush (stdout);
-}
-
-
-static void
-request_succeeded (const void *buffer, size_t buflen)
-{
-  size_t len;
-
-  putchar (0x81); /* Simple error/success response. */
-
-  len = 4 + buflen;
-  putchar ((len >> 24) & 0xff);
-  putchar ((len >> 16) & 0xff);
-  putchar ((len >>  8) & 0xff);
-  putchar ((len      ) & 0xff);
-
-  /* Error code. */
-  putchar (0);
-  putchar (0);
-  putchar (0);
-  putchar (0);
-
-  /* Optional reponse string. */
-  if (buffer)
-    fwrite (buffer, buflen, 1, stdout);
-
-  fflush (stdout);
-}
-
-
-
-static unsigned long
-read_32 (FILE *fp)
-{
-  int c1, c2, c3, c4;
-
-  c1 = getc (fp);
-  c2 = getc (fp);
-  c3 = getc (fp);
-  c4 = getc (fp);
-  if (c1 == EOF || c2 == EOF || c3 == EOF || c4 == EOF)
-    {
-      fprintf (stderr, PGM ": premature EOF while parsing request\n");
-      exit (1);
-    }
-  return (c1 << 24) | (c2 << 16) | (c3 << 8) | c4;
-}
-
-
-
-static const char *
-pcsc_error_string (long err)
-{
-  const char *s;
-
-  if (!err)
-    return "okay";
-  if ((err & 0x80100000) != 0x80100000)
-    return "invalid PC/SC error code";
-  err &= 0xffff;
-  switch (err)
-    {
-    case 0x0002: s = "cancelled"; break;
-    case 0x000e: s = "can't dispose"; break;
-    case 0x0008: s = "insufficient buffer"; break;
-    case 0x0015: s = "invalid ATR"; break;
-    case 0x0003: s = "invalid handle"; break;
-    case 0x0004: s = "invalid parameter"; break;
-    case 0x0005: s = "invalid target"; break;
-    case 0x0011: s = "invalid value"; break;
-    case 0x0006: s = "no memory"; break;
-    case 0x0013: s = "comm error"; break;
-    case 0x0001: s = "internal error"; break;
-    case 0x0014: s = "unknown error"; break;
-    case 0x0007: s = "waited too long"; break;
-    case 0x0009: s = "unknown reader"; break;
-    case 0x000a: s = "timeout"; break;
-    case 0x000b: s = "sharing violation"; break;
-    case 0x000c: s = "no smartcard"; break;
-    case 0x000d: s = "unknown card"; break;
-    case 0x000f: s = "proto mismatch"; break;
-    case 0x0010: s = "not ready"; break;
-    case 0x0012: s = "system cancelled"; break;
-    case 0x0016: s = "not transacted"; break;
-    case 0x0017: s = "reader unavailable"; break;
-    case 0x0065: s = "unsupported card"; break;
-    case 0x0066: s = "unresponsive card"; break;
-    case 0x0067: s = "unpowered card"; break;
-    case 0x0068: s = "reset card"; break;
-    case 0x0069: s = "removed card"; break;
-    case 0x006a: s = "inserted card"; break;
-    case 0x001f: s = "unsupported feature"; break;
-    case 0x0019: s = "PCI too small"; break;
-    case 0x001a: s = "reader unsupported"; break;
-    case 0x001b: s = "duplicate reader"; break;
-    case 0x001c: s = "card unsupported"; break;
-    case 0x001d: s = "no service"; break;
-    case 0x001e: s = "service stopped"; break;
-    default:     s = "unknown PC/SC error code"; break;
-    }
-  return s;
-}
-
-static void
-load_pcsc_driver (const char *libname)
-{
-  void *handle;
-
-  handle = dlopen (libname, RTLD_LAZY);
-  if (!handle)
-    {
-      fprintf (stderr, PGM ": failed to open driver '%s': %s",
-               libname, dlerror ());
-      exit (1);
-    }
-
-  pcsc_establish_context = dlsym (handle, "SCardEstablishContext");
-  pcsc_release_context   = dlsym (handle, "SCardReleaseContext");
-  pcsc_list_readers      = dlsym (handle, "SCardListReaders");
-  pcsc_get_status_change = dlsym (handle, "SCardGetStatusChange");
-  pcsc_connect           = dlsym (handle, "SCardConnect");
-  pcsc_reconnect         = dlsym (handle, "SCardReconnect");
-  pcsc_disconnect        = dlsym (handle, "SCardDisconnect");
-  pcsc_status            = dlsym (handle, "SCardStatus");
-  pcsc_begin_transaction = dlsym (handle, "SCardBeginTransaction");
-  pcsc_end_transaction   = dlsym (handle, "SCardEndTransaction");
-  pcsc_transmit          = dlsym (handle, "SCardTransmit");
-  pcsc_set_timeout       = dlsym (handle, "SCardSetTimeout");
-  pcsc_control           = dlsym (handle, "SCardControl");
-
-  if (!pcsc_establish_context
-      || !pcsc_release_context
-      || !pcsc_list_readers
-      || !pcsc_get_status_change
-      || !pcsc_connect
-      || !pcsc_reconnect
-      || !pcsc_disconnect
-      || !pcsc_status
-      || !pcsc_begin_transaction
-      || !pcsc_end_transaction
-      || !pcsc_transmit
-      || !pcsc_control
-      /* || !pcsc_set_timeout */)
-    {
-      /* Note that set_timeout is currently not used and also not
-         available under Windows. */
-      fprintf (stderr,
-               "apdu_open_reader: invalid PC/SC driver "
-               "(%d%d%d%d%d%d%d%d%d%d%d%d%d)\n",
-               !!pcsc_establish_context,
-               !!pcsc_release_context,
-               !!pcsc_list_readers,
-               !!pcsc_get_status_change,
-               !!pcsc_connect,
-               !!pcsc_reconnect,
-               !!pcsc_disconnect,
-               !!pcsc_status,
-               !!pcsc_begin_transaction,
-               !!pcsc_end_transaction,
-               !!pcsc_transmit,
-               !!pcsc_set_timeout,
-               !!pcsc_control );
-      dlclose (handle);
-      exit (1);
-    }
-}
-
-
-
-
-/* Handle a open request.  The argument is expected to be a string
-   with the port identification.  ARGBUF is always guaranteed to be
-   terminted by a 0 which is not counted in ARGLEN.  We may modifiy
-   ARGBUF. */
-static void
-handle_open (unsigned char *argbuf, size_t arglen)
-{
-  long err;
-  const char * portstr;
-  char *list = NULL;
-  pcsc_dword_t nreader, atrlen;
-  char *p;
-  pcsc_dword_t card_state, card_protocol;
-  unsigned char atr[33];
-
-  /* Make sure there is only the port string */
-  if (arglen != strlen ((char*)argbuf))
-    bad_request ("OPEN");
-  portstr = (char*)argbuf;
-
-  if (driver_is_open)
-    {
-      fprintf (stderr, PGM ": PC/SC has already been opened\n");
-      request_failed (-1);
-      return;
-    }
-
-  err = pcsc_establish_context (PCSC_SCOPE_SYSTEM, NULL, NULL, &pcsc_context);
-  if (err)
-    {
-      fprintf (stderr, PGM": pcsc_establish_context failed: %s (0x%lx)\n",
-               pcsc_error_string (err), err);
-      request_failed (err);
-      return;
-    }
-
-  err = pcsc_list_readers (pcsc_context, NULL, NULL, &nreader);
-  if (!err)
-    {
-      list = malloc (nreader+1); /* Better add 1 for safety reasons. */
-      if (!list)
-        {
-          fprintf (stderr, PGM": error allocating memory for reader list\n");
-          exit (1);
-        }
-      err = pcsc_list_readers (pcsc_context, NULL, list, &nreader);
-    }
-  if (err)
-    {
-      fprintf (stderr, PGM": pcsc_list_readers failed: %s (0x%lx)\n",
-               pcsc_error_string (err), err);
-      pcsc_release_context (pcsc_context);
-      free (list);
-      request_failed (err);
-      return;
-    }
-
-  p = list;
-  while (nreader)
-    {
-      if (!*p && !p[1])
-        break;
-      fprintf (stderr, PGM": detected reader '%s'\n", p);
-      if (nreader < (strlen (p)+1))
-        {
-          fprintf (stderr, PGM": invalid response from pcsc_list_readers\n");
-          break;
-        }
-      nreader -= strlen (p)+1;
-      p += strlen (p) + 1;
-    }
-
-  current_rdrname = malloc (strlen (portstr && *portstr? portstr:list)+1);
-  if (!current_rdrname)
-    {
-      fprintf (stderr, PGM": error allocating memory for reader name\n");
-      exit (1);
-    }
-  strcpy (current_rdrname, portstr && *portstr? portstr:list);
-  free (list);
-
-  err = pcsc_connect (pcsc_context,
-                      current_rdrname,
-                      PCSC_SHARE_EXCLUSIVE,
-                      PCSC_PROTOCOL_T0|PCSC_PROTOCOL_T1,
-                      &pcsc_card,
-                      &pcsc_protocol);
-  if (err == 0x8010000c) /* No smartcard.  */
-    {
-      pcsc_card = 0;
-    }
-  else if (err)
-    {
-      fprintf (stderr, PGM": pcsc_connect failed: %s (0x%lx)\n",
-               pcsc_error_string (err), err);
-      pcsc_release_context (pcsc_context);
-      free (current_rdrname);
-      current_rdrname = NULL;
-      pcsc_card = 0;
-      pcsc_protocol = 0;
-      request_failed (err);
-      return;
-    }
-
-  current_atrlen = 0;
-  if (!err)
-    {
-      char reader[250];
-      pcsc_dword_t readerlen;
-
-      atrlen = 33;
-      readerlen = sizeof reader -1;
-      err = pcsc_status (pcsc_card,
-                         reader, &readerlen,
-                         &card_state, &card_protocol,
-                         atr, &atrlen);
-      if (err)
-        fprintf (stderr, PGM": pcsc_status failed: %s (0x%lx)\n",
-                 pcsc_error_string (err), err);
-      else
-        {
-          if (atrlen >= sizeof atr || atrlen >= sizeof current_atr)
-            {
-              fprintf (stderr, PGM": ATR returned by pcsc_status"
-                       " is too large\n");
-              exit (4);
-            }
-          memcpy (current_atr, atr, atrlen);
-          current_atrlen = atrlen;
-        }
-    }
-
-  driver_is_open = 1;
-  request_succeeded (current_atr, current_atrlen);
-}
-
-
-
-/* Handle a close request.  We expect no arguments.  We may modifiy
-   ARGBUF. */
-static void
-handle_close (unsigned char *argbuf, size_t arglen)
-{
-  (void)argbuf;
-  (void)arglen;
-
-  if (!driver_is_open)
-    {
-      fprintf (stderr, PGM ": PC/SC has not yet been opened\n");
-      request_failed (-1);
-      return;
-    }
-
-  free (current_rdrname);
-  current_rdrname = NULL;
-  pcsc_release_context (pcsc_context);
-  pcsc_card = 0;
-  pcsc_protocol = 0;
-
-  request_succeeded (NULL, 0);
-}
-
-
-
-/* Handle a status request.  We expect no arguments.  We may modifiy
-   ARGBUF. */
-static void
-handle_status (unsigned char *argbuf, size_t arglen)
-{
-  long err;
-  struct pcsc_readerstate_s rdrstates[1];
-  int status;
-  unsigned char buf[20];
-
-  (void)argbuf;
-  (void)arglen;
-
-  if (!driver_is_open)
-    {
-      fprintf (stderr, PGM ": PC/SC has not yet been opened\n");
-      request_failed (-1);
-      return;
-    }
-
-  memset (rdrstates, 0, sizeof *rdrstates);
-  rdrstates[0].reader = current_rdrname;
-  rdrstates[0].current_state = PCSC_STATE_UNAWARE;
-  err = pcsc_get_status_change (pcsc_context,
-                                0,
-                                rdrstates, 1);
-  if (err == 0x8010000a) /* Timeout.  */
-    err = 0;
-  if (err)
-    {
-      fprintf (stderr, PGM": pcsc_get_status_change failed: %s (0x%lx)\n",
-               pcsc_error_string (err), err);
-      request_failed (err);
-      return;
-    }
-
-  status = 0;
-  if ( !(rdrstates[0].event_state & PCSC_STATE_UNKNOWN) )
-    {
-      if ( (rdrstates[0].event_state & PCSC_STATE_PRESENT) )
-       {
-         status |= 2;
-         if ( !(rdrstates[0].event_state & PCSC_STATE_MUTE) )
-           status |= 4;
-       }
-      /* We indicate a useful card if it is not in use by another
-         application.  This is because we only use exclusive access
-         mode.  */
-      if ( (status & 6) == 6
-           && !(rdrstates[0].event_state & PCSC_STATE_INUSE) )
-        status |= 1;
-    }
-
-  /* First word is identical to the one used by apdu.c. */
-  buf[0] = 0;
-  buf[1] = 0;
-  buf[2] = 0;
-  buf[3] = status;
-  /* The second word is the native PCSC state.  */
-  buf[4] = (rdrstates[0].event_state >> 24);
-  buf[5] = (rdrstates[0].event_state >> 16);
-  buf[6] = (rdrstates[0].event_state >>  8);
-  buf[7] = (rdrstates[0].event_state >>  0);
-  /* The third word is the protocol. */
-  buf[8]  = (pcsc_protocol >> 24);
-  buf[9]  = (pcsc_protocol >> 16);
-  buf[10] = (pcsc_protocol >> 8);
-  buf[11] = (pcsc_protocol);
-
-  request_succeeded (buf, 8);
-}
-
-
-/* Handle a reset request.  We expect no arguments.  We may modifiy
-   ARGBUF. */
-static void
-handle_reset (unsigned char *argbuf, size_t arglen)
-{
-  long err;
-  char reader[250];
-  pcsc_dword_t nreader, atrlen;
-  pcsc_dword_t card_state, card_protocol;
-
-  (void)argbuf;
-  (void)arglen;
-
-  if (!driver_is_open)
-    {
-      fprintf (stderr, PGM ": PC/SC has not yet been opened\n");
-      request_failed (-1);
-      return;
-    }
-
-  if (pcsc_card)
-    {
-      err = pcsc_disconnect (pcsc_card, PCSC_LEAVE_CARD);
-      if (err == 0x80100003)  /* Invalid handle.  (already disconnected) */
-        err = 0;
-      if (err)
-        {
-          fprintf (stderr, PGM": pcsc_disconnect failed: %s (0x%lx)\n",
-                     pcsc_error_string (err), err);
-          request_failed (err);
-          return;
-        }
-      pcsc_card = 0;
-    }
-
-  err = pcsc_connect (pcsc_context,
-                      current_rdrname,
-                      PCSC_SHARE_EXCLUSIVE,
-                      PCSC_PROTOCOL_T0|PCSC_PROTOCOL_T1,
-                      &pcsc_card,
-                      &pcsc_protocol);
-  if (err)
-    {
-      fprintf (stderr, PGM": pcsc_connect failed: %s (0x%lx)\n",
-               pcsc_error_string (err), err);
-      pcsc_card = 0;
-      request_failed (err);
-      return;
-    }
-
-
-  atrlen = 33;
-  nreader = sizeof reader - 1;
-  err = pcsc_status (pcsc_card,
-                     reader, &nreader,
-                     &card_state, &card_protocol,
-                     current_atr, &atrlen);
-  if (err)
-    {
-      fprintf (stderr, PGM": pcsc_status failed: %s (0x%lx)\n",
-               pcsc_error_string (err), err);
-      current_atrlen = 0;
-      request_failed (err);
-      return;
-    }
-
-  request_succeeded (current_atr, current_atrlen);
-}
-
-
-
-/* Handle a transmit request.  The argument is expected to be a buffer
-   with the APDU.  We may modifiy ARGBUF. */
-static void
-handle_transmit (unsigned char *argbuf, size_t arglen)
-{
-  long err;
-  struct pcsc_io_request_s send_pci;
-  pcsc_dword_t recv_len;
-  unsigned char buffer[4096];
-
-  /* The apdu should at least be one byte. */
-  if (!arglen)
-    bad_request ("TRANSMIT");
-
-  if (!driver_is_open)
-    {
-      fprintf (stderr, PGM ": PC/SC has not yet been opened\n");
-      request_failed (-1);
-      return;
-    }
-  if ((pcsc_protocol & PCSC_PROTOCOL_T1))
-    send_pci.protocol = PCSC_PROTOCOL_T1;
-  else
-    send_pci.protocol = PCSC_PROTOCOL_T0;
-  send_pci.pci_len = sizeof send_pci;
-  recv_len = sizeof (buffer);
-  err = pcsc_transmit (pcsc_card, &send_pci, argbuf, arglen,
-                       NULL, buffer, &recv_len);
-  if (err)
-    {
-      if (verbose)
-        fprintf (stderr, PGM": pcsc_transmit failed: %s (0x%lx)\n",
-                 pcsc_error_string (err), err);
-      request_failed (err);
-      return;
-    }
-  request_succeeded (buffer, recv_len);
-}
-
-
-/* Handle a control request.  The argument is expected to be a buffer
-   which contains CONTROL_CODE (4-byte) and INPUT_BYTES.
- */
-static void
-handle_control (unsigned char *argbuf, size_t arglen)
-{
-  long err;
-  pcsc_dword_t ioctl_code;
-  pcsc_dword_t recv_len = 1024;
-  unsigned char buffer[1024];
-
-  if (arglen < 4)
-    bad_request ("CONTROL");
-
-  ioctl_code = (argbuf[0] << 24) | (argbuf[1] << 16) | (argbuf[2] << 8) | argbuf[3];
-  argbuf += 4;
-  arglen -= 4;
-
-  recv_len = sizeof (buffer);
-  err = pcsc_control (pcsc_card, ioctl_code, argbuf, arglen,
-                      buffer, recv_len, &recv_len);
-  if (err)
-    {
-      if (verbose)
-        fprintf (stderr, PGM": pcsc_control failed: %s (0x%lx)\n",
-                 pcsc_error_string (err), err);
-      request_failed (err);
-      return;
-    }
-  request_succeeded (buffer, recv_len);
-}
-
-
-static void
-print_version (int with_help)
-{
-  fputs (MYVERSION_LINE "\n"
-         "Copyright (C) 2004 Free Software Foundation, Inc.\n"
-         "This program comes with ABSOLUTELY NO WARRANTY.\n"
-         "This is free software, and you are welcome to redistribute it\n"
-         "under certain conditions. See the file COPYING for details.\n",
-         stdout);
-
-  if (with_help)
-    fputs ("\n"
-          "Usage: " PGM " [OPTIONS] API-NUMBER [LIBNAME]\n"
-          "Helper to connect scdaemon to the PC/SC library\n"
-          "\n"
-          "  --verbose   enable extra informational output\n"
-          "  --version   print version of the program and exit\n"
-          "  --help      display this help and exit\n"
-          BUGREPORT_LINE, stdout );
-
-  exit (0);
-}
-
-
-int
-main (int argc, char **argv)
-{
-  int last_argc = -1;
-  int api_number = 0;
-  int c;
-
-  if (argc)
-    {
-      argc--; argv++;
-    }
-  while (argc && last_argc != argc )
-    {
-      last_argc = argc;
-      if (!strcmp (*argv, "--"))
-        {
-          argc--; argv++;
-          break;
-        }
-      else if (!strcmp (*argv, "--version"))
-        print_version (0);
-      else if (!strcmp (*argv, "--help"))
-        print_version (1);
-      else if (!strcmp (*argv, "--verbose"))
-        {
-          verbose = 1;
-          argc--; argv++;
-        }
-    }
-  if (argc != 1 && argc != 2)
-    {
-      fprintf (stderr, "usage: " PGM " API-NUMBER [LIBNAME]\n");
-      exit (1);
-    }
-
-  api_number = atoi (*argv);
-  argv++; argc--;
-  if (api_number != 1)
-    {
-      fprintf (stderr, PGM ": api-number %d is not valid\n", api_number);
-      exit (1);
-    }
-
-  load_pcsc_driver (argc? *argv : DEFAULT_PCSC_DRIVER);
-
-  while ((c = getc (stdin)) != EOF)
-    {
-      size_t arglen;
-      unsigned char argbuffer[2048];
-
-      arglen = read_32 (stdin);
-      if (arglen >= sizeof argbuffer - 1)
-        {
-          fprintf (stderr, PGM ": request too long\n");
-          exit (1);
-        }
-      if (arglen && fread (argbuffer, arglen, 1, stdin) != 1)
-        {
-          fprintf (stderr, PGM ": error reading request: %s\n",
-                   strerror (errno));
-          exit (1);
-        }
-      argbuffer[arglen] = 0;
-      switch (c)
-        {
-        case 1:
-          handle_open (argbuffer, arglen);
-          break;
-
-        case 2:
-          handle_close (argbuffer, arglen);
-          exit (0);
-          break;
-
-        case 3:
-          handle_transmit (argbuffer, arglen);
-          break;
-
-        case 4:
-          handle_status (argbuffer, arglen);
-          break;
-
-        case 5:
-          handle_reset (argbuffer, arglen);
-          break;
-
-        case 6:
-          handle_control (argbuffer, arglen);
-          break;
-
-        default:
-          fprintf (stderr, PGM ": invalid request 0x%02X\n", c);
-          exit (1);
-        }
-    }
-  return 0;
-}
-
-
-
-/*
-Local Variables:
-compile-command: "gcc -Wall -g -o pcsc-wrapper pcsc-wrapper.c -ldl"
-End:
-*/
diff --git a/scd/sc-copykeys.c b/scd/sc-copykeys.c
deleted file mode 100644 (file)
index eb246c4..0000000
+++ /dev/null
@@ -1,715 +0,0 @@
-/* sc-copykeys.c - A tool to store keys on a smartcard.
- *     Copyright (C) 2003 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "scdaemon.h"
-#include <gcrypt.h>
-
-#include "../common/ttyio.h"
-#include "../common/simple-pwquery.h"
-#include "iso7816.h"
-#include "apdu.h" /* for open_reader */
-#include "atr.h"
-#include "app-common.h"
-
-#define _(a) (a)
-
-
-enum cmd_and_opt_values
-{ oVerbose       = 'v',
-  oReaderPort     = 500,
-  octapiDriver,
-  oDebug,
-  oDebugAll,
-
-aTest };
-
-
-static ARGPARSE_OPTS opts[] = {
-
-  { 301, NULL, 0, "@Options:\n " },
-
-  { oVerbose, "verbose",   0, "verbose" },
-  { oReaderPort, "reader-port", 2, "|N|connect to reader at port N"},
-  { octapiDriver, "ctapi-driver", 2, "NAME|use NAME as ctAPI driver"},
-  { oDebug,    "debug"     ,4|16, "set debugging flags"},
-  { oDebugAll, "debug-all" ,0, "enable full debugging"},
-  {0}
-};
-
-
-static void copykeys (APP app, const char *fname);
-
-
-static const char *
-my_strusage (int level)
-{
-  const char *p;
-  switch (level)
-    {
-    case 11: p = "sc-copykeys (GnuPG)";
-      break;
-    case 13: p = VERSION; break;
-    case 17: p = PRINTABLE_OS_NAME; break;
-    case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
-
-    case 1:
-    case 40: p =  _("Usage: sc-copykeys [options] (-h for help)\n");
-      break;
-    case 41: p = _("Syntax: sc-copykeys [options] "
-                   "file-with-key\n"
-                    "Copy keys to a smartcards\n");
-    break;
-
-    default: p = NULL;
-    }
-  return p;
-}
-
-
-int
-main (int argc, char **argv )
-{
-  ARGPARSE_ARGS pargs;
-  int slot, rc;
-  const char *reader_port = NULL;
-  struct app_ctx_s appbuf;
-
-  memset (&appbuf, 0, sizeof appbuf);
-
-  set_strusage (my_strusage);
-  gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
-  log_set_prefix ("sc-copykeys", 1);
-
-  /* check that the libraries are suitable.  Do it here because
-     the option parsing may need services of the library */
-  if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
-    {
-      log_fatal (_("%s is too old (need %s, have %s)\n"), "libgcrypt",
-                 NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
-    }
-
-  setup_libgcrypt_logging ();
-  gcry_control (GCRYCTL_DISABLE_SECMEM, 0); /* FIXME - we want to use it */
-  /* FIXME? gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);*/
-
-  pargs.argc = &argc;
-  pargs.argv = &argv;
-  pargs.flags=  1;  /* do not remove the args */
-  while (arg_parse (&pargs, opts) )
-    {
-      switch (pargs.r_opt)
-        {
-        case oVerbose: opt.verbose++; break;
-        case oDebug: opt.debug |= pargs.r.ret_ulong; break;
-        case oDebugAll: opt.debug = ~0; break;
-        case oReaderPort: reader_port = pargs.r.ret_str; break;
-        case octapiDriver: opt.ctapi_driver = pargs.r.ret_str; break;
-        default : pargs.err = 2; break;
-       }
-    }
-  if (log_get_errorcount(0))
-    exit(2);
-
-  if (argc != 1)
-    usage (1);
-
-  slot = apdu_open_reader (reader_port);
-  if (slot == -1)
-    exit (1);
-  if (apdu_connect (slot))
-    exit (1);
-
-  /* FIXME: Use select_application. */
-  appbuf.slot = slot;
-  rc = app_select_openpgp (&appbuf);
-  if (rc)
-    {
-      log_error ("selecting openpgp failed: %s\n", gpg_strerror (rc));
-      exit (1);
-    }
-  appbuf.initialized = 1;
-  log_info ("openpgp application selected\n");
-
-  copykeys (&appbuf, *argv);
-
-
-  return 0;
-}
-
-
-
-void
-send_status_info (CTRL ctrl, const char *keyword, ...)
-{
-  /* DUMMY */
-}
-
-
-
-static char *
-read_file (const char *fname, size_t *r_length)
-{
-  FILE *fp;
-  struct stat st;
-  char *buf;
-  size_t buflen;
-
-  fp = fname? fopen (fname, "rb") : stdin;
-  if (!fp)
-    {
-      log_error ("can't open '%s': %s\n",
-                 fname? fname: "[stdin]", strerror (errno));
-      return NULL;
-    }
-
-  if (fstat (fileno(fp), &st))
-    {
-      log_error ("can't stat '%s': %s\n",
-                 fname? fname: "[stdin]", strerror (errno));
-      if (fname)
-        fclose (fp);
-      return NULL;
-    }
-
-  buflen = st.st_size;
-  buf = xmalloc (buflen+1);
-  if (fread (buf, buflen, 1, fp) != 1)
-    {
-      log_error ("error reading '%s': %s\n",
-                 fname? fname: "[stdin]", strerror (errno));
-      if (fname)
-        fclose (fp);
-      xfree (buf);
-      return NULL;
-    }
-  if (fname)
-    fclose (fp);
-
-  *r_length = buflen;
-  return buf;
-}
-
-
-static gcry_sexp_t
-read_key (const char *fname)
-{
-  char *buf;
-  size_t buflen;
-  gcry_sexp_t private;
-  int rc;
-
-  buf = read_file (fname, &buflen);
-  if (!buf)
-    return NULL;
-
-  rc = gcry_sexp_new (&private, buf, buflen, 1);
-  if (rc)
-    {
-      log_error ("gcry_sexp_new failed: %s\n", gpg_strerror (rc));
-      return NULL;
-    }
-  xfree (buf);
-
-  return private;
-}
-
-
-
-static gcry_mpi_t *
-sexp_to_kparms (gcry_sexp_t sexp, unsigned long *created)
-{
-  gcry_sexp_t list, l2;
-  const char *name;
-  const char *s;
-  size_t n;
-  int i, idx;
-  const char *elems;
-  gcry_mpi_t *array;
-
-  *created = 0;
-  list = gcry_sexp_find_token (sexp, "private-key", 0 );
-  if(!list)
-    return NULL;
-
-  /* quick hack to get the creation time. */
-  l2 = gcry_sexp_find_token (list, "created", 0);
-  if (l2 && (name = gcry_sexp_nth_data (l2, 1, &n)))
-    {
-      char *tmp = xmalloc (n+1);
-      memcpy (tmp, name, n);
-      tmp[n] = 0;
-      *created = strtoul (tmp, NULL, 10);
-      xfree (tmp);
-    }
-  gcry_sexp_release (l2);
-  l2 = gcry_sexp_cadr (list);
-  gcry_sexp_release (list);
-  list = l2;
-  name = gcry_sexp_nth_data (list, 0, &n);
-  if(!name || n != 3 || memcmp (name, "rsa", 3))
-    {
-      gcry_sexp_release (list);
-      return NULL;
-    }
-
-  /* Parameter names used with RSA. */
-  elems = "nedpqu";
-  array = xcalloc (strlen(elems) + 1, sizeof *array);
-  for (idx=0, s=elems; *s; s++, idx++ )
-    {
-      l2 = gcry_sexp_find_token (list, s, 1);
-      if (!l2)
-        {
-          for (i=0; i<idx; i++)
-            gcry_mpi_release (array[i]);
-          xfree (array);
-          gcry_sexp_release (list);
-          return NULL; /* required parameter not found */
-       }
-      array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
-      gcry_sexp_release (l2);
-      if (!array[idx])
-        {
-          for (i=0; i<idx; i++)
-            gcry_mpi_release (array[i]);
-          xfree (array);
-          gcry_sexp_release (list);
-          return NULL; /* required parameter is invalid */
-       }
-    }
-
-  gcry_sexp_release (list);
-  return array;
-}
-
-
-/* Return true if the SHA1 fingerprint FPR consists only of zeroes. */
-static int
-fpr_is_zero (const char *fpr)
-{
-  int i;
-
-  for (i=0; i < 20 && !fpr[i]; i++)
-    ;
-  return (i == 20);
-}
-
-
-static void
-show_sha1_fpr (const unsigned char *fpr)
-{
-  int i;
-
-  if (fpr)
-    {
-      for (i=0; i < 20 ; i+=2, fpr += 2 )
-        {
-          if (i == 10 )
-            tty_printf (" ");
-          tty_printf (" %02X%02X", *fpr, fpr[1]);
-        }
-    }
-  else
-    tty_printf (" [none]");
-  tty_printf ("\n");
-}
-
-/* Query the card, show a list of already stored keys and ask the user
-   where to store the key.  Returns the key number or 0 for cancel
-   operation. */
-static int
-query_card (APP app)
-{
-  int keyno = 0;
-  char *serialno, *disp_name, *pubkey_url;
-  unsigned char *fpr1, *fpr2, *fpr3;
-
-
-  if (app_openpgp_cardinfo (app,
-                            &serialno,
-                            &disp_name,
-                            &pubkey_url,
-                            &fpr1, &fpr2, &fpr3))
-    return 0;
-
-
-  for (;;)
-    {
-      char *answer;
-
-      tty_printf ("\n");
-
-      tty_printf ("Serial number ....: %s\n",
-                  serialno? serialno : "[none]");
-      tty_printf ("Name of cardholder: %s\n",
-                  disp_name && *disp_name? disp_name : "[not set]");
-      tty_printf ("URL of public key : %s\n",
-                  pubkey_url && *pubkey_url? pubkey_url : "[not set]");
-      tty_printf ("Signature key ....:");
-      show_sha1_fpr (fpr1);
-      tty_printf ("Encryption key....:");
-      show_sha1_fpr (fpr2);
-      tty_printf ("Authentication key:");
-      show_sha1_fpr (fpr3);
-
-      tty_printf ("\n"
-                  "1 - store as signature key and reset usage counter\n"
-                  "2 - store as encryption key\n"
-                  "3 - store as authentication key\n"
-                  "Q - quit\n"
-                  "\n");
-
-      answer = tty_get("Your selection? ");
-      tty_kill_prompt();
-      if (strlen (answer) != 1)
-        ;
-      else if ( *answer == '1' )
-        {
-          if ( (fpr1 && !fpr_is_zero (fpr1)) )
-            {
-              tty_printf ("\n");
-              log_error ("WARNING: signature key does already exists!\n");
-              tty_printf ("\n");
-              if ( tty_get_answer_is_yes ("Replace existing key? ") )
-                {
-                  keyno = 1;
-                  break;
-                }
-            }
-          else
-            {
-              keyno = 1;
-              break;
-            }
-        }
-      else if ( *answer == '2' )
-        {
-          if ( (fpr2 && !fpr_is_zero (fpr2)) )
-            {
-              tty_printf ("\n");
-              log_error ("WARNING: encryption key does already exists!\n");
-              tty_printf ("\n");
-              if ( tty_get_answer_is_yes ("Replace existing key? ") )
-                {
-                  keyno = 2;
-                  break;
-                }
-            }
-          else
-            {
-              keyno = 2;
-              break;
-            }
-        }
-      else if ( *answer == '3' )
-        {
-          if ( (fpr3 && !fpr_is_zero (fpr3)) )
-            {
-              tty_printf ("\n");
-              log_error ("WARNING: authentication key does already exists!\n");
-              tty_printf ("\n");
-              if ( tty_get_answer_is_yes ("Replace existing key? ") )
-                {
-                  keyno = 3;
-                  break;
-                }
-            }
-          else
-            {
-              keyno = 3;
-              break;
-            }
-        }
-      else if ( *answer == 'q' || *answer == 'Q')
-        {
-          keyno = 0;
-          break;
-        }
-    }
-
-  xfree (serialno);
-  xfree (disp_name);
-  xfree (pubkey_url);
-  xfree (fpr1);
-  xfree (fpr2);
-  xfree (fpr3);
-
-  return keyno;
-}
-
-
-/* Callback function to ask for a PIN. */
-static gpg_error_t
-pincb (void *arg, const char *prompt, char **pinvalue)
-{
-  char *pin = xstrdup ("12345678");
-
-/*    pin = simple_pwquery (NULL, NULL, prompt, */
-/*                          "We need the admin's PIN to store the key on the card", */
-/*                          0, NULL); */
-/*    if (!pin) */
-/*      return gpg_error (GPG_ERR_CANCELED); */
-
-
-
-  *pinvalue = pin;
-  return 0;
-}
-
-
-/* This function expects a file (or NULL for stdin) with the secret
-   and public key parameters.  This file should consist of an
-   S-expression as used by gpg-agent. Only the unprotected format is
-   supported.  Example:
-
-   (private-key
-    (rsa
-     (n #00e0ce9..[some bytes not shown]..51#)
-     (e #010001#)
-     (d #046129F..[some bytes not shown]..81#)
-     (p #00e861b..[some bytes not shown]..f1#)
-     (q #00f7a7c..[some bytes not shown]..61#)
-     (u #304559a..[some bytes not shown]..9b#))
-    (uri http://foo.bar x-foo:whatever_you_want))
-
-*/
-static void
-copykeys (APP app, const char *fname)
-{
-  int rc;
-  gcry_sexp_t private;
-  gcry_mpi_t *mpis, rsa_n, rsa_e, rsa_p, rsa_q;
-  unsigned int nbits;
-  size_t n;
-  unsigned char *template, *tp;
-  unsigned char m[128], e[4];
-  size_t mlen, elen;
-  unsigned long creation_date;
-  time_t created_at;
-  int keyno;
-
-  if (!strcmp (fname, "-"))
-    fname = NULL;
-
-  private = read_key (fname);
-  if (!private)
-    exit (1);
-
-  mpis = sexp_to_kparms (private, &creation_date);
-  if (!creation_date)
-    {
-      log_info ("no creation date found - assuming current date\n");
-      created_at = time (NULL);
-    }
-  else
-    created_at = creation_date;
-  gcry_sexp_release (private);
-  if (!mpis)
-    {
-      log_error ("invalid structure of key file or not RSA\n");
-      exit (1);
-    }
-  /* MPIS is now an array with the key parameters as defined by OpenPGP. */
-  rsa_n = mpis[0];
-  rsa_e = mpis[1];
-  gcry_mpi_release (mpis[2]);
-  rsa_p = mpis[3];
-  rsa_q = mpis[4];
-  gcry_mpi_release (mpis[5]);
-  xfree (mpis);
-
-  nbits = gcry_mpi_get_nbits (rsa_e);
-  if (nbits < 2 || nbits > 32)
-    {
-      log_error ("public exponent too large (more than 32 bits)\n");
-      goto failure;
-    }
-  nbits = gcry_mpi_get_nbits (rsa_p);
-  if (nbits != 512)
-    {
-      log_error ("length of first RSA prime is not 512\n");
-      goto failure;
-    }
-  nbits = gcry_mpi_get_nbits (rsa_q);
-  if (nbits != 512)
-    {
-      log_error ("length of second RSA prime is not 512\n");
-      goto failure;
-    }
-
-  nbits = gcry_mpi_get_nbits (rsa_n);
-  if (nbits != 1024)
-    {
-      log_error ("length of RSA modulus is not 1024\n");
-      goto failure;
-    }
-
-  keyno = query_card (app);
-  if (!keyno)
-    goto failure;
-
-  /* Build the private key template as described in section 4.3.3.6 of
-     the specs.
-                   0xC0   <length> public exponent
-                   0xC1   <length> prime p
-                   0xC2   <length> prime q  */
-  template = tp = xmalloc (1+2 + 1+1+4 + 1+1+64 + 1+1+64);
-  *tp++ = 0xC0;
-  *tp++ = 4;
-  rc = gcry_mpi_print (GCRYMPI_FMT_USG, tp, 4, &n, rsa_e);
-  if (rc)
-    {
-      log_error ("mpi_print failed: %s\n", gpg_strerror (rc));
-      goto failure;
-    }
-  assert (n <= 4);
-  memcpy (e, tp, n);
-  elen = n;
-  if (n != 4)
-    {
-      memmove (tp+4-n, tp, 4-n);
-      memset (tp, 0, 4-n);
-    }
-  tp += 4;
-
-  *tp++ = 0xC1;
-  *tp++ = 64;
-  rc = gcry_mpi_print (GCRYMPI_FMT_USG, tp, 64, &n, rsa_p);
-  if (rc)
-    {
-      log_error ("mpi_print failed: %s\n", gpg_strerror (rc));
-      goto failure;
-    }
-  assert (n == 64);
-  tp += 64;
-
-  *tp++ = 0xC2;
-  *tp++ = 64;
-  rc = gcry_mpi_print (GCRYMPI_FMT_USG, tp, 64, &n, rsa_q);
-  if (rc)
-    {
-      log_error ("mpi_print failed: %s\n", gpg_strerror (rc));
-      goto failure;
-    }
-  assert (n == 64);
-  tp += 64;
-  assert (tp - template == 138);
-
-  /* (we need the modulus to calculate the fingerprint) */
-  rc = gcry_mpi_print (GCRYMPI_FMT_USG, m, 128, &n, rsa_n);
-  if (rc)
-    {
-      log_error ("mpi_print failed: %s\n", gpg_strerror (rc));
-      goto failure;
-    }
-  assert (n == 128);
-  mlen = 128;
-
-
-  rc = app_openpgp_storekey (app, keyno,
-                             template, tp - template,
-                             created_at,
-                             m, mlen,
-                             e, elen,
-                             pincb, NULL);
-
-  if (rc)
-    {
-      log_error ("error storing key: %s\n", gpg_strerror (rc));
-      goto failure;
-    }
-  log_info ("key successfully stored\n");
-  {
-    unsigned char *mm, *ee;
-    size_t mmlen, eelen;
-    int i;
-
-    rc = app_openpgp_readkey (app, keyno, &mm, &mmlen, &ee, &eelen);
-    if (rc)
-      {
-        log_error ("error reading key back: %s\n", gpg_strerror (rc));
-        goto failure;
-      }
-
-    /* Strip leading zeroes. */
-    for (i=0; i < mmlen && !mm[i]; i++)
-      ;
-    mmlen -= i;
-    memmove (mm, mm+i, mmlen);
-    for (i=0; i < eelen && !ee[i]; i++)
-      ;
-    eelen -= i;
-    memmove (ee, ee+i, eelen);
-
-    if (eelen != elen || mmlen != mlen)
-      {
-        log_error ("key parameter length mismatch (n=%u/%u, e=%u/%u)\n",
-                   (unsigned int)mlen, (unsigned int)mmlen,
-                   (unsigned int)elen, (unsigned int)eelen);
-        xfree (mm);
-        xfree (ee);
-        goto failure;
-      }
-
-    if (memcmp (m, mm, mlen))
-      {
-        log_error ("key parameter n mismatch\n");
-        log_printhex ("original n: ", m, mlen);
-        log_printhex ("  copied n: ", mm, mlen);
-        xfree (mm);
-        xfree (ee);
-        goto failure;
-      }
-    if (memcmp (e, ee, elen))
-      {
-        log_error ("key parameter e mismatch\n");
-        log_printhex ("original e: ", e, elen);
-        log_printhex ("  copied e: ", ee, elen);
-        xfree (mm);
-        xfree (ee);
-        goto failure;
-      }
-    xfree (mm);
-    xfree (ee);
-  }
-
-
-  gcry_mpi_release (rsa_e);
-  gcry_mpi_release (rsa_p);
-  gcry_mpi_release (rsa_q);
-  gcry_mpi_release (rsa_n);
-  return;
-
- failure:
-  gcry_mpi_release (rsa_e);
-  gcry_mpi_release (rsa_p);
-  gcry_mpi_release (rsa_q);
-  gcry_mpi_release (rsa_n);
-  exit (1);
-}
index 35ada43..1a95ba7 100644 (file)
@@ -124,7 +124,7 @@ const char *scd_get_socket_name (void);
 void initialize_module_command (void);
 int  scd_command_handler (ctrl_t, int);
 void send_status_info (ctrl_t ctrl, const char *keyword, ...)
-     GNUPG_GCC_A_SENTINEL(1);
+     GPGRT_ATTR_SENTINEL(1);
 void send_status_direct (ctrl_t ctrl, const char *keyword, const char *args);
 void scd_update_reader_status_file (void);
 
index 9fc74c3..30e4fb3 100644 (file)
@@ -241,7 +241,7 @@ int  gpgsm_parse_validation_model (const char *model);
 /*-- server.c --*/
 void gpgsm_server (certlist_t default_recplist);
 gpg_error_t gpgsm_status (ctrl_t ctrl, int no, const char *text);
-gpg_error_t gpgsm_status2 (ctrl_t ctrl, int no, ...) GNUPG_GCC_A_SENTINEL(0);
+gpg_error_t gpgsm_status2 (ctrl_t ctrl, int no, ...) GPGRT_ATTR_SENTINEL(0);
 gpg_error_t gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text,
                                         gpg_err_code_t ec);
 gpg_error_t gpgsm_proxy_pinentry_notify (ctrl_t ctrl,
index 5c28954..496b1a6 100644 (file)
@@ -18,7 +18,7 @@
 
 EXTRA_DIST = \
        Manifest watchgnupg.c \
-       addgnupghome applygnupgdefaults gpgsm-gencert.sh \
+       addgnupghome applygnupgdefaults \
        lspgpot mail-signed-keys convert-from-106 sockprox.c \
        ccidmon.c ChangeLog-2011 gpg-connect-agent-w32info.rc
 
@@ -34,7 +34,6 @@ AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) $(LIBASSUAN_CFLAGS)
 
 sbin_SCRIPTS = addgnupghome applygnupgdefaults
 
-bin_SCRIPTS = gpgsm-gencert.sh
 if HAVE_USTAR
 # bin_SCRIPTS += gpg-zip
 noinst_SCRIPTS = gpg-zip
diff --git a/tools/gpgsm-gencert.sh b/tools/gpgsm-gencert.sh
deleted file mode 100755 (executable)
index b209c8e..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-#!/bin/sh
-#                                                              -*- sh -*-
-# gpgsm-gencert.c - Generate X.509 certificates through GPGSM.  
-#      Copyright (C) 2004, 2005 Free Software Foundation, Inc.
-#
-# This file is part of GnuPG.
-#
-# GnuPG is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# GnuPG is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
-
-set -e
-
-ASSUAN_FP_IN=4
-ASSUAN_FP_OUT=5
-
-ASSUAN_COMMANDS="\
-INPUT FD=$ASSUAN_FP_IN\n\
-OUTPUT FD=$ASSUAN_FP_OUT --armor\n\
-GENKEY\n\
-BYE\n"
-
-ANSWER=""
-
-query_user()
-{
-    message=$1; shift
-    
-    echo "$message" >&2
-    echo -n "> " >&2
-    read answer
-
-    ANSWER=$answer;
-}
-
-query_user_menu()
-{
-    message=$1; shift
-    i=0
-    
-    echo "$message" >&2
-    for choice in "$@"; do
-       i=$(expr $i + 1)
-       echo " [$i] $choice" >&2
-    done
-
-    while true; do
-       j=1
-       echo -n "Your selection: " >&2
-       read idx
-
-       while [ $j -lt $i -o $j -eq $i ]; do
-           if [ "$idx" = $j ]; then
-               break
-           fi
-           j=$(expr $j + 1)
-       done
-       if [ $j -lt $i -o $j -eq $i ]; then
-           break
-       fi
-    done
-
-    i=0
-    for choice in "$@"; do
-       i=$(expr $i + 1)
-       if [ $i -eq $idx ]; then
-           ANSWER=$1
-           break;
-       fi
-       shift
-    done
-    
-    echo "You selected: $ANSWER" >&2
-}
-
-
-echo "WARNING: This script is deprecated; please use" >&2
-echo "           gpgsm --gen-key" >&2
-echo "         instead." >&2
-KEY_TYPE=""
-while [ -z "$KEY_TYPE" ]; do
-  query_user_menu "Key type" "RSA" "Existing key" "Direct from card"
-  case "$ANSWER" in
-    RSA)
-      KEY_TYPE=$ANSWER
-      query_user_menu "Key length" "1024" "2048"
-      KEY_LENGTH=$ANSWER
-      KEY_GRIP=
-      ;;
-    Existing*)
-      # User requested to use an existing key; need to set some dummy defaults
-      query_user "Keygrip "
-      if [ -n "$ANSWER" ]; then
-        KEY_TYPE=RSA 
-        KEY_LENGTH=1024
-        KEY_GRIP=$ANSWER
-      fi
-      ;;
-    Direct*)
-      tmp=$(echo 'SCD SERIALNO' | gpg-connect-agent | \
-            awk '$2 == "SERIALNO" {print $3}') 
-      if [ -z "$tmp" ]; then
-          echo "No card found" >&2
-      else
-        echo "Card with S/N $tmp found" >&2
-        tmp=$(echo 'SCD LEARN --force' | gpg-connect-agent | \
-              awk '$2 == "KEYPAIRINFO" {printf " %s", $4}')
-        sshid=$(echo 'SCD GETATTR $AUTHKEYID' | gpg-connect-agent | \
-                awk '$2 == "$AUTHKEYID" {print $3}') 
-        [ -n "$sshid" ] && echo "gpg-agent uses $sshid as ssh key" >&2
-        query_user_menu "Select key " $tmp "back"
-        if [ "$ANSWER" != "back" ]; then
-          KEY_TYPE="card:$ANSWER"
-          KEY_LENGTH=
-          KEY_GRIP=
-        fi
-      fi
-      ;;
-    *)
-      exit 1
-      ;;   
-  esac
-done
-
-query_user_menu "Key usage" "sign, encrypt" "sign" "encrypt"
-KEY_USAGE=$ANSWER
-
-query_user "Name (DN)"
-NAME=$ANSWER
-
-EMAIL_ADDRESSES=
-LF=
-while : ; do
-  query_user "E-Mail addresses (end with an empty line)"
-  [ -z "$ANSWER" ] && break
-  EMAIL_ADDRESSES="${EMAIL_ADDRESSES}${LF}Name-Email: $ANSWER"
-  LF='
-'
-done
-
-DNS_ADDRESSES=
-LF=
-while : ; do
-  query_user "DNS Names (optional; end with an empty line)"
-  [ -z "$ANSWER" ] && break
-  DNS_ADDRESSES="${DNS_ADDRESSES}${LF}Name-DNS: $ANSWER"
-  LF='
-'
-done
-
-URI_ADDRESSES=
-LF=
-while : ; do
-  query_user "URIs (optional; end with an empty line)"
-  [ -z "$ANSWER" ] && break
-  URI_ADDRESSES="${URI_ADDRESSES}${LF}Name-URI: $ANSWER"
-  LF='
-'
-done
-
-file_parameter=$(mktemp "/tmp/gpgsm.XXXXXX")
-outfile=$(mktemp "/tmp/gpgsm.XXXXXX")
-
-
-(
-cat <<EOF
-Key-Type: $KEY_TYPE
-Key-Length: $KEY_LENGTH
-Key-Usage: $KEY_USAGE
-Name-DN: $NAME
-EOF
-[ -n "$KEY_GRIP" ] && echo "Key-Grip: $KEY_GRIP"
-[ -n "$EMAIL_ADDRESSES" ] && echo "$EMAIL_ADDRESSES"
-[ -n "$DNS_ADDRESSES" ] && echo "$DNS_ADDRESSES"
-[ -n "$URI_ADDRESSES" ] && echo "$URI_ADDRESSES"
-) > "$file_parameter"
-
-
-echo 'Parameters for certificate request to create:' >&2
-cat -n "$file_parameter" >&2
-echo  >&2
-
-query_user_menu "Really create such a CSR?" "yes" "no"
-[ "$ANSWER" != "yes" ] && exit 1
-    
-
-printf "$ASSUAN_COMMANDS" | \
-     gpgsm --no-log-file --debug-level none --debug-none \
-           --server 4< "$file_parameter" 5>"$outfile" >/dev/null
-
-cat "$outfile"
-
-rm "$file_parameter" "$outfile"
-exit 0