[git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.12-13-g9fd6ba2

by Werner Koch cvs at cvs.gnupg.org
Tue Jan 22 10:18:14 CET 2019


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, STABLE-BRANCH-2-2 has been updated
       via  9fd6ba268f1fdf77cc5baa6e8fd3ab28e432e49b (commit)
       via  d4082ff430afe670510d2c1c7ea66ee9ddcbe505 (commit)
       via  9309175de8c76de44021c25c7885355ff1a9b67b (commit)
       via  11a65159f997ccd69ecb9d867c1f3d0c4d8837d6 (commit)
       via  f5d3b982e44c5cfc60e9936020102a598b635187 (commit)
      from  9dc76d599cd4c86d3c187d078daad1144a92564c (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 9fd6ba268f1fdf77cc5baa6e8fd3ab28e432e49b
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Jan 8 11:21:07 2019 +0100

    doc: Mark keyserver-options timeout and http-proxy as obsolete.
    
    --
    
    (cherry picked from commit 6c000d4b78b836686e5a2789cc88a41e465e4400)

diff --git a/doc/gpg.texi b/doc/gpg.texi
index 1eed9fa..1597f9e 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -1895,32 +1895,12 @@ are available for all keyserver types, some common options are:
   retrieving keys by subkey id.
 
   @item timeout
-  Tell the keyserver helper program how long (in seconds) to try and
-  perform a keyserver action before giving up. Note that performing
-  multiple actions at the same time uses this timeout value per action.
-  For example, when retrieving multiple keys via @option{--receive-keys}, the
-  timeout applies separately to each key retrieval, and not to the
-  @option{--receive-keys} command as a whole. Defaults to 30 seconds.
-
-  @item http-proxy=@var{value}
-  This option is deprecated.
-  Set the proxy to use for HTTP and HKP keyservers.
-  This overrides any proxy defined in @file{dirmngr.conf}.
-
-  @item verbose
-  This option has no more function since GnuPG 2.1.  Use the
-  @code{dirmngr} configuration options instead.
-
-  @item debug
-  This option has no more function since GnuPG 2.1.  Use the
-  @code{dirmngr} configuration options instead.
-
-  @item check-cert
-  This option has no more function since GnuPG 2.1.  Use the
-  @code{dirmngr} configuration options instead.
-
+  @itemx http-proxy=@var{value}
+  @itemx verbose
+  @itemx debug
+  @itemx check-cert
   @item ca-cert-file
-  This option has no more function since GnuPG 2.1.  Use the
+  These options have no more function since GnuPG 2.1.  Use the
   @code{dirmngr} configuration options instead.
 
 @end table

commit d4082ff430afe670510d2c1c7ea66ee9ddcbe505
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Jan 21 14:06:51 2019 +0100

    scd: Add option --clear to PASSWD.
    
    * scd/command.c (cmd_passwd): Add option --clear.
    (send_status_printf): New.
    * scd/app-common.h (APP_CHANGE_FLAG_CLEAR): New.
    * scd/app-nks.c (do_change_pin): Return an error if that option is
    used.
    * scd/app-openpgp.c (do_change_pin): Ditto.
    --
    
    Card application may support this option to clear the PIN verification
    status of a specific PIN.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>
    (cherry picked from commit 29929e65521279eabc98a67c766fe485057405a9)

diff --git a/po/Makevars b/po/Makevars
index b538f19..270ac59 100644
--- a/po/Makevars
+++ b/po/Makevars
@@ -62,6 +62,7 @@ XGETTEXT_OPTIONS = \
 	--flag=print_further_info:1:c-format     \
 	--flag=write_status_printf:2:c-format    \
 	--flag=gpgconf_write_status:2:c-format   \
+        --flag=send_status_printf:3:c-format     \
 	--flag=wks_write_status:2:c-format
 
 # This is the copyright holder that gets inserted into the header of the
diff --git a/scd/app-common.h b/scd/app-common.h
index 38e6cc6..37e3c60 100644
--- a/scd/app-common.h
+++ b/scd/app-common.h
@@ -26,8 +26,9 @@
 #include <ksba.h>
 
 
-#define APP_CHANGE_FLAG_RESET    1
-#define APP_CHANGE_FLAG_NULLPIN  2
+#define APP_CHANGE_FLAG_RESET    1  /* PIN Reset mode.  */
+#define APP_CHANGE_FLAG_NULLPIN  2  /* NULL PIN mode.  */
+#define APP_CHANGE_FLAG_CLEAR    4  /* Clear the given PIN.  */
 
 /* Bit flags set by the decipher function into R_INFO.  */
 #define APP_DECIPHER_INFO_NOPAD  1  /* Padding has been removed.  */
diff --git a/scd/app-nks.c b/scd/app-nks.c
index 801ab90..0f38e7c 100644
--- a/scd/app-nks.c
+++ b/scd/app-nks.c
@@ -1169,6 +1169,9 @@ do_change_pin (app_t app, ctrl_t ctrl,  const char *pwidstr,
   if (!newdesc)
     return gpg_error (GPG_ERR_INV_ID);
 
+  if ((flags & APP_CHANGE_FLAG_CLEAR))
+    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+
   err = switch_application (app, is_sigg);
   if (err)
     return err;
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index fa23fbe..760332e 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -2584,10 +2584,14 @@ do_change_pin (app_t app, ctrl_t ctrl,  const char *chvnostr,
   int pinlen = 0;
 
   (void)ctrl;
+
   memset (&pininfo, 0, sizeof pininfo);
   pininfo.fixedlen = -1;
   pininfo.minlen = minlen;
 
+  if ((flags & APP_CHANGE_FLAG_CLEAR))
+    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+
   if (reset_mode && chvno == 3)
     {
       rc = gpg_error (GPG_ERR_INV_ID);
diff --git a/scd/app.c b/scd/app.c
index a82db26..c430579 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -938,7 +938,7 @@ app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode,
 }
 
 
-/* Perform a VERIFY operation without doing anything lese.  This may
+/* Perform a VERIFY operation without doing anything else.  This may
    be used to initialize a the PIN cache for long lasting other
    operations.  Its use is highly application dependent. */
 gpg_error_t
diff --git a/scd/command.c b/scd/command.c
index 8fa4b38..ec6793a 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -1192,12 +1192,13 @@ cmd_random (assuan_context_t ctx, char *line)
 
 

 static const char hlp_passwd[] =
-  "PASSWD [--reset] [--nullpin] <chvno>\n"
+  "PASSWD [--reset] [--nullpin] [--clear] <chvno>\n"
   "\n"
   "Change the PIN or, if --reset is given, reset the retry counter of\n"
   "the card holder verification vector CHVNO.  The option --nullpin is\n"
-  "used for TCOS cards to set the initial PIN.  The format of CHVNO\n"
-  "depends on the card application.";
+  "used for TCOS cards to set the initial PIN.  The option --clear clears\n"
+  "the security status associated with the PIN so that the PIN needs to\n"
+  "be presented again. The format of CHVNO depends on the card application.";
 static gpg_error_t
 cmd_passwd (assuan_context_t ctx, char *line)
 {
@@ -1210,6 +1211,8 @@ cmd_passwd (assuan_context_t ctx, char *line)
     flags |= APP_CHANGE_FLAG_RESET;
   if (has_option (line, "--nullpin"))
     flags |= APP_CHANGE_FLAG_NULLPIN;
+  if (has_option (line, "--clear"))
+    flags |= APP_CHANGE_FLAG_CLEAR;
 
   line = skip_options (line);
 
@@ -1220,6 +1223,11 @@ cmd_passwd (assuan_context_t ctx, char *line)
     line++;
   *line = 0;
 
+  /* Do not allow other flags aside of --clear. */
+  if ((flags & APP_CHANGE_FLAG_CLEAR) && (flags & ~APP_CHANGE_FLAG_CLEAR))
+    return set_error (GPG_ERR_UNSUPPORTED_OPERATION,
+                      "--clear used with other options");
+
   if ((rc = open_card (ctrl)))
     return rc;
 
@@ -1899,6 +1907,26 @@ send_status_direct (ctrl_t ctrl, const char *keyword, const char *args)
 }
 
 
+/* This status functions expects a printf style format string.  No
+ * filtering of the data is done instead the orintf formatted data is
+ * send using assuan_send_status. */
+gpg_error_t
+send_status_printf (ctrl_t ctrl, const char *keyword, const char *format, ...)
+{
+  gpg_error_t err;
+  va_list arg_ptr;
+  assuan_context_t ctx;
+
+  if (!ctrl || !ctrl->server_local || !(ctx = ctrl->server_local->assuan_ctx))
+    return 0;
+
+  va_start (arg_ptr, format);
+  err = vprint_assuan_status (ctx, keyword, format, arg_ptr);
+  va_end (arg_ptr);
+  return err;
+}
+
+
 void
 popup_prompt (void *opaque, int on)
 {
diff --git a/scd/scdaemon.h b/scd/scdaemon.h
index 238e6a8..73589ad 100644
--- a/scd/scdaemon.h
+++ b/scd/scdaemon.h
@@ -123,6 +123,9 @@ int  scd_command_handler (ctrl_t, int);
 void send_status_info (ctrl_t ctrl, const char *keyword, ...)
      GPGRT_ATTR_SENTINEL(1);
 void send_status_direct (ctrl_t ctrl, const char *keyword, const char *args);
+gpg_error_t send_status_printf (ctrl_t ctrl, const char *keyword,
+                                const char *format, ...) GPGRT_ATTR_PRINTF(3,4);
+
 void popup_prompt (void *opaque, int on);
 void send_client_notifications (app_t app, int removal);
 void scd_kick_the_loop (void);

commit 9309175de8c76de44021c25c7885355ff1a9b67b
Author: Werner Koch <wk at gnupg.org>
Date:   Sun Jan 20 11:41:23 2019 +0100

    scd: One new and one improved 7816 function.
    
    * scd/apdu.c (apdu_send_direct): New arg R_SW.
    * scd/command.c (cmd_apdu): Ditto.
    * scd/iso7816.c (iso7816_apdu_direct): New arg R_SW.
    (iso7816_general_authenticate): New.
    * scd/app-nks.c (get_chv_status, get_nks_version): Pass NULL for new
    arg.
    --
    
    iso7816_general_authenticate will be used for the PIV card support.
    The new arg to iso7816_apdu_direct and apdu_send_direct allows to get
    the raw status word back without the need to handle an output buffer.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>
    (cherry picked from commit 70bb5c7931598590b1acfae90bf4657f5911d2d3)

diff --git a/scd/apdu.c b/scd/apdu.c
index 7ed0b97..af77570 100644
--- a/scd/apdu.c
+++ b/scd/apdu.c
@@ -3062,19 +3062,25 @@ apdu_send_simple (int slot, int extended_mode,
 
 
 /* This is a more generic version of the apdu sending routine.  It
-   takes an already formatted APDU in APDUDATA or length APDUDATALEN
-   and returns with an APDU including the status word.  With
-   HANDLE_MORE set to true this function will handle the MORE DATA
-   status and return all APDUs concatenated with one status word at
-   the end.  If EXTENDED_LENGTH is != 0 extended lengths are allowed
-   with a max. result data length of EXTENDED_LENGTH bytes.  The
-   function does not return a regular status word but 0 on success.
-   If the slot is locked, the function returns immediately with an
-   error.  */
+ * takes an already formatted APDU in APDUDATA or length APDUDATALEN
+ * and returns with an APDU including the status word.  With
+ * HANDLE_MORE set to true this function will handle the MORE DATA
+ * status and return all APDUs concatenated with one status word at
+ * the end.  If EXTENDED_LENGTH is != 0 extended lengths are allowed
+ * with a max. result data length of EXTENDED_LENGTH bytes.  The
+ * function does not return a regular status word but 0 on success.
+ * If the slot is locked, the function returns immediately with an
+ * error.
+ *
+ * Out of historical reasons the function returns 0 on success and
+ * outs the status word at the end of the result to be able to get the
+ * status word in the case of a not provided RETBUF, R_SW can be used
+ * to store the SW.  But note that R_SW qill only be set if the
+ * function returns 0. */
 int
 apdu_send_direct (int slot, size_t extended_length,
                   const unsigned char *apdudata, size_t apdudatalen,
-                  int handle_more,
+                  int handle_more, unsigned int *r_sw,
                   unsigned char **retbuf, size_t *retbuflen)
 {
 #define SHORT_RESULT_BUFFER_SIZE 258
@@ -3281,9 +3287,13 @@ apdu_send_direct (int slot, size_t extended_length,
       (*retbuf)[(*retbuflen)++] = sw;
     }
 
+  if (r_sw)
+    *r_sw = sw;
+
   if (DBG_CARD_IO && retbuf)
     log_printhex ("      dump: ", *retbuf, *retbuflen);
 
+
   return 0;
 }
 
diff --git a/scd/apdu.h b/scd/apdu.h
index f7bc0bc..6240134 100644
--- a/scd/apdu.h
+++ b/scd/apdu.h
@@ -137,7 +137,7 @@ int apdu_send_le (int slot, int extended_mode,
                   unsigned char **retbuf, size_t *retbuflen);
 int apdu_send_direct (int slot, size_t extended_length,
                       const unsigned char *apdudata, size_t apdudatalen,
-                      int handle_more,
+                      int handle_more, unsigned int *r_sw,
                       unsigned char **retbuf, size_t *retbuflen);
 const char *apdu_get_reader_name (int slot);
 
diff --git a/scd/app-nks.c b/scd/app-nks.c
index 9e720f0..801ab90 100644
--- a/scd/app-nks.c
+++ b/scd/app-nks.c
@@ -273,7 +273,7 @@ get_chv_status (app_t app, int sigg, int pwid)
   command[3] = pwid;
 
   if (apdu_send_direct (app->slot, 0, (unsigned char *)command,
-                        4, 0, &result, &resultlen))
+                        4, 0, NULL, &result, &resultlen))
     rc = -1; /* Error. */
   else if (resultlen < 2)
     rc = -1; /* Error. */
@@ -1300,7 +1300,7 @@ get_nks_version (int slot)
   int type;
 
   if (iso7816_apdu_direct (slot, "\x80\xaa\x06\x00\x00", 5, 0,
-                           &result, &resultlen))
+                           NULL, &result, &resultlen))
     return 2; /* NKS 2 does not support this command.  */
 
   /* Example value:    04 11 19 22 21 6A 20 80 03 03 01 01 01 00 00 00
diff --git a/scd/command.c b/scd/command.c
index 0a96546..8fa4b38 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -333,7 +333,7 @@ static const char hlp_learn[] =
   "or a \"CANCEL\" to force the function to terminate with a Cancel\n"
   "error message.\n"
   "\n"
-  "With the option --keypairinfo only KEYPARIINFO lstatus lines are\n"
+  "With the option --keypairinfo only KEYPARIINFO status lines are\n"
   "returned.\n"
   "\n"
   "The response of this command is a list of status lines formatted as\n"
@@ -346,6 +346,7 @@ static const char hlp_learn[] =
   "    P15     = PKCS-15 structure used\n"
   "    DINSIG  = DIN SIG\n"
   "    OPENPGP = OpenPGP card\n"
+  "    PIV     = PIV card\n"
   "    NKS     = NetKey card\n"
   "\n"
   "are implemented.  These strings are aliases for the AID\n"
@@ -1640,7 +1641,7 @@ cmd_apdu (assuan_context_t ctx, char *line)
 
       rc = apdu_send_direct (app->slot, exlen,
                              apdu, apdulen, handle_more,
-                             &result, &resultlen);
+                             NULL, &result, &resultlen);
       if (rc)
         log_error ("apdu_send_direct failed: %s\n", gpg_strerror (rc));
       else
diff --git a/scd/iso7816.c b/scd/iso7816.c
index 081b080..9e55073 100644
--- a/scd/iso7816.c
+++ b/scd/iso7816.c
@@ -50,6 +50,7 @@
 #define CMD_PUT_DATA    0xDA
 #define CMD_MSE         0x22
 #define CMD_PSO         0x2A
+#define CMD_GENERAL_AUTHENTICATE  0x87
 #define CMD_INTERNAL_AUTHENTICATE 0x88
 #define CMD_GENERATE_KEYPAIR      0x47
 #define CMD_GET_CHALLENGE         0x84
@@ -209,24 +210,28 @@ iso7816_list_directory (int slot, int list_dirs,
    internally.  The return value is a gpg error code (i.e. a mapped
    status word).  This is basically the same as apdu_send_direct but
    it maps the status word and does not return it in the result
-   buffer.  */
+   buffer.  However, it R_SW is not NULL the status word is stored
+   R_SW for closer inspection. */
 gpg_error_t
 iso7816_apdu_direct (int slot, const void *apdudata, size_t apdudatalen,
-                     int handle_more,
+                     int handle_more, unsigned int *r_sw,
                      unsigned char **result, size_t *resultlen)
 {
-  int sw;
+  int sw, sw2;
 
-  if (!result || !resultlen)
-    return gpg_error (GPG_ERR_INV_VALUE);
-  *result = NULL;
-  *resultlen = 0;
+  if (result)
+    {
+      *result = NULL;
+      *resultlen = 0;
+    }
 
   sw = apdu_send_direct (slot, 0, apdudata, apdudatalen, handle_more,
-                         result, resultlen);
+                         &sw2, result, resultlen);
   if (!sw)
     {
-      if (*resultlen < 2)
+      if (!result)
+        sw = sw2;
+      else if (*resultlen < 2)
         sw = SW_HOST_GENERAL_ERROR;
       else
         {
@@ -235,13 +240,15 @@ iso7816_apdu_direct (int slot, const void *apdudata, size_t apdudatalen,
           (*resultlen)--;
         }
     }
-  if (sw != SW_SUCCESS)
+  if (sw != SW_SUCCESS && result)
     {
       /* Make sure that pending buffers are released. */
       xfree (*result);
       *result = NULL;
       *resultlen = 0;
     }
+  if (r_sw)
+    *r_sw = sw;
   return map_sw (sw);
 }
 
@@ -541,7 +548,7 @@ iso7816_decipher (int slot, int extended_mode,
 }
 
 
-/*  For LE see do_generate_keypair.  */
+/* For LE see do_generate_keypair.  */
 gpg_error_t
 iso7816_internal_authenticate (int slot, int extended_mode,
                                const unsigned char *data, size_t datalen,
@@ -578,6 +585,44 @@ iso7816_internal_authenticate (int slot, int extended_mode,
 }
 
 
+/* For LE see do_generate_keypair.  */
+gpg_error_t
+iso7816_general_authenticate (int slot, int extended_mode,
+                              int algoref, int keyref,
+                              const unsigned char *data, size_t datalen,
+                              int le,
+                              unsigned char **result, size_t *resultlen)
+{
+  int sw;
+
+  if (!data || !datalen || !result || !resultlen)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  *result = NULL;
+  *resultlen = 0;
+
+  if (!extended_mode)
+    le = 256;  /* Ignore provided Le and use what apdu_send uses. */
+  else if (le >= 0 && le < 256)
+    le = 256;
+
+  sw = apdu_send_le (slot, extended_mode,
+                     0x00, CMD_GENERAL_AUTHENTICATE, algoref, keyref,
+                     datalen, (const char*)data,
+                     le,
+                     result, resultlen);
+  if (sw != SW_SUCCESS)
+    {
+      /* Make sure that pending buffers are released. */
+      xfree (*result);
+      *result = NULL;
+      *resultlen = 0;
+      return map_sw (sw);
+    }
+
+  return 0;
+}
+
+
 /* LE is the expected return length.  This is usually 0 except if
    extended length mode is used and more than 256 byte will be
    returned.  In that case a value of -1 uses a large default
diff --git a/scd/iso7816.h b/scd/iso7816.h
index 4c71bbd..44781ff 100644
--- a/scd/iso7816.h
+++ b/scd/iso7816.h
@@ -58,7 +58,7 @@ gpg_error_t iso7816_list_directory (int slot, int list_dirs,
                                     unsigned char **result, size_t *resultlen);
 gpg_error_t iso7816_apdu_direct (int slot,
                                  const void *apdudata, size_t apdudatalen,
-                                 int handle_more,
+                                 int handle_more, unsigned int *r_sw,
                                  unsigned char **result, size_t *resultlen);
 gpg_error_t iso7816_check_pinpad (int slot, int command,
                                   pininfo_t *pininfo);
@@ -97,6 +97,13 @@ gpg_error_t iso7816_internal_authenticate (int slot, int extended_mode,
                                    const unsigned char *data, size_t datalen,
                                    int le,
                                    unsigned char **result, size_t *resultlen);
+gpg_error_t iso7816_general_authenticate (int slot, int extended_mode,
+                                          int algoref, int keyref,
+                                          const unsigned char *data,
+                                          size_t datalen,
+                                          int le,
+                                          unsigned char **result,
+                                          size_t *resultlen);
 gpg_error_t iso7816_generate_keypair (int slot, int extended_mode,
                                     const char *data, size_t datalen,
                                     int le,

commit 11a65159f997ccd69ecb9d867c1f3d0c4d8837d6
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Jan 17 15:42:33 2019 +0100

    ssh: Simplify the curve name lookup.
    
    * agent/command-ssh.c (struct ssh_key_type_spec): Add field
    alt_curve_name.
    (ssh_key_types): Add some alternate curve names.
    (ssh_identifier_from_curve_name): Lookup also bey alternative names
    and return the canonical name.
    (ssh_key_to_blob): Simplify the ECDSA case by using gcry_pk_get_curve
    instead of the explicit mapping.
    (ssh_receive_key): Likewise.  Use ssh_identifier_from_curve_name to
    validate the curve name.  Remove the reverse mapping because since
    GnuPG-2.2 Libgcrypt 1.7 is required.
    (ssh_handler_request_identities): Log an error message.
    --
    
    This change will make it easier to support other curves, in particular
    those from tokens.  Libgcrypt has a large list of alias names which we
    now use to to make the mapping more flexible.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>
    (cherry picked from commit d93797c8a7892fe26672c551017468e9f8099ef6)

diff --git a/agent/command-ssh.c b/agent/command-ssh.c
index 9255830..3cfd8aa 100644
--- a/agent/command-ssh.c
+++ b/agent/command-ssh.c
@@ -195,9 +195,14 @@ struct ssh_key_type_spec
      algorithm.  */
   ssh_signature_encoder_t signature_encoder;
 
-  /* The name of the ECC curve or NULL.  */
+  /* The name of the ECC curve or NULL for non-ECC algos.  This is the
+   * canonical name for the curve as specified by RFC-5656.  */
   const char *curve_name;
 
+  /* An alias for curve_name or NULL.  Actually this is Libcgrypt's
+   * primary name of the curve.  */
+  const char *alt_curve_name;
+
   /* The hash algorithm to be used with this key.  0 for using the
      default.  */
   int hash_algo;
@@ -292,68 +297,71 @@ static const ssh_key_type_spec_t ssh_key_types[] =
     {
       "ssh-ed25519", "Ed25519", GCRY_PK_EDDSA, "qd",  "q", "rs", "qd",
       NULL,                 ssh_signature_encoder_eddsa,
-      "Ed25519", 0,               SPEC_FLAG_IS_EdDSA
+      "Ed25519", NULL, 0,   SPEC_FLAG_IS_EdDSA
     },
     {
       "ssh-rsa", "RSA", GCRY_PK_RSA, "nedupq", "en",   "s",  "nedpqu",
       ssh_key_modifier_rsa, ssh_signature_encoder_rsa,
-      NULL, 0,                    SPEC_FLAG_USE_PKCS1V2
+      NULL, NULL, 0,        SPEC_FLAG_USE_PKCS1V2
     },
     {
       "ssh-dss", "DSA", GCRY_PK_DSA, "pqgyx",  "pqgy", "rs", "pqgyx",
       NULL,                 ssh_signature_encoder_dsa,
-      NULL, 0, 0
+      NULL, NULL, 0, 0
     },
     {
       "ecdsa-sha2-nistp256", "ECDSA", GCRY_PK_ECC, "qd",  "q", "rs", "qd",
       NULL,                 ssh_signature_encoder_ecdsa,
-      "nistp256", GCRY_MD_SHA256, SPEC_FLAG_IS_ECDSA
+      "nistp256", "NIST P-256", GCRY_MD_SHA256, SPEC_FLAG_IS_ECDSA
     },
     {
       "ecdsa-sha2-nistp384", "ECDSA", GCRY_PK_ECC, "qd",  "q", "rs", "qd",
       NULL,                 ssh_signature_encoder_ecdsa,
-      "nistp384", GCRY_MD_SHA384, SPEC_FLAG_IS_ECDSA
+      "nistp384", "NIST P-384", GCRY_MD_SHA384, SPEC_FLAG_IS_ECDSA
     },
     {
       "ecdsa-sha2-nistp521", "ECDSA", GCRY_PK_ECC, "qd",  "q", "rs", "qd",
       NULL,                 ssh_signature_encoder_ecdsa,
-      "nistp521", GCRY_MD_SHA512, SPEC_FLAG_IS_ECDSA
+      "nistp521", "NIST P-521", GCRY_MD_SHA512, SPEC_FLAG_IS_ECDSA
     },
     {
       "ssh-ed25519-cert-v01 at openssh.com", "Ed25519",
       GCRY_PK_EDDSA, "qd",  "q", "rs", "qd",
       NULL,                 ssh_signature_encoder_eddsa,
-      "Ed25519", 0, SPEC_FLAG_IS_EdDSA | SPEC_FLAG_WITH_CERT
+      "Ed25519", NULL, 0,   SPEC_FLAG_IS_EdDSA | SPEC_FLAG_WITH_CERT
     },
     {
       "ssh-rsa-cert-v01 at openssh.com", "RSA",
       GCRY_PK_RSA, "nedupq", "en",   "s",  "nedpqu",
       ssh_key_modifier_rsa, ssh_signature_encoder_rsa,
-      NULL, 0, SPEC_FLAG_USE_PKCS1V2 | SPEC_FLAG_WITH_CERT
+      NULL, NULL, 0, SPEC_FLAG_USE_PKCS1V2 | SPEC_FLAG_WITH_CERT
     },
     {
       "ssh-dss-cert-v01 at openssh.com", "DSA",
       GCRY_PK_DSA, "pqgyx",  "pqgy", "rs", "pqgyx",
       NULL,                 ssh_signature_encoder_dsa,
-      NULL, 0, SPEC_FLAG_WITH_CERT | SPEC_FLAG_WITH_CERT
+      NULL, NULL, 0, SPEC_FLAG_WITH_CERT | SPEC_FLAG_WITH_CERT
     },
     {
       "ecdsa-sha2-nistp256-cert-v01 at openssh.com", "ECDSA",
       GCRY_PK_ECC, "qd",  "q", "rs", "qd",
       NULL,                 ssh_signature_encoder_ecdsa,
-      "nistp256", GCRY_MD_SHA256, SPEC_FLAG_IS_ECDSA | SPEC_FLAG_WITH_CERT
+      "nistp256", "NIST P-256", GCRY_MD_SHA256,
+                                SPEC_FLAG_IS_ECDSA | SPEC_FLAG_WITH_CERT
     },
     {
       "ecdsa-sha2-nistp384-cert-v01 at openssh.com", "ECDSA",
       GCRY_PK_ECC, "qd",  "q", "rs", "qd",
       NULL,                 ssh_signature_encoder_ecdsa,
-      "nistp384", GCRY_MD_SHA384, SPEC_FLAG_IS_ECDSA | SPEC_FLAG_WITH_CERT
+      "nistp384", "NIST P-384", GCRY_MD_SHA384,
+                                SPEC_FLAG_IS_ECDSA | SPEC_FLAG_WITH_CERT
     },
     {
       "ecdsa-sha2-nistp521-cert-v01 at openssh.com", "ECDSA",
       GCRY_PK_ECC, "qd",  "q", "rs", "qd",
       NULL,                 ssh_signature_encoder_ecdsa,
-      "nistp521", GCRY_MD_SHA512, SPEC_FLAG_IS_ECDSA | SPEC_FLAG_WITH_CERT
+      "nistp521", "NIST P-521", GCRY_MD_SHA512,
+                                SPEC_FLAG_IS_ECDSA | SPEC_FLAG_WITH_CERT
     }
   };
 
@@ -384,16 +392,24 @@ realloc_secure (void *a, size_t n)
 
 
 /* Lookup the ssh-identifier for the ECC curve CURVE_NAME.  Returns
-   NULL if not found.  */
+ * NULL if not found.  If found the ssh indetifier is returned and a
+ * pointer to the canonical curve name as specified for ssh is stored
+ * at R_CANON_NAME.  */
 static const char *
-ssh_identifier_from_curve_name (const char *curve_name)
+ssh_identifier_from_curve_name (const char *curve_name,
+                                const char **r_canon_name)
 {
   int i;
 
   for (i = 0; i < DIM (ssh_key_types); i++)
     if (ssh_key_types[i].curve_name
-        && !strcmp (ssh_key_types[i].curve_name, curve_name))
-      return ssh_key_types[i].ssh_identifier;
+        && (!strcmp (ssh_key_types[i].curve_name, curve_name)
+            || (ssh_key_types[i].alt_curve_name
+                && !strcmp (ssh_key_types[i].alt_curve_name, curve_name))))
+      {
+        *r_canon_name = ssh_key_types[i].curve_name;
+        return ssh_key_types[i].ssh_identifier;
+      }
 
   return NULL;
 }
@@ -1844,7 +1860,6 @@ ssh_key_to_blob (gcry_sexp_t sexp, int with_secret,
   gpg_error_t err = 0;
   gcry_sexp_t value_list = NULL;
   gcry_sexp_t value_pair = NULL;
-  char *curve_name = NULL;
   estream_t stream = NULL;
   void *blob = NULL;
   size_t blob_size;
@@ -1862,7 +1877,7 @@ ssh_key_to_blob (gcry_sexp_t sexp, int with_secret,
       goto out;
     }
 
-  /* Get the type of the key extpression.  */
+  /* Get the type of the key expression.  */
   data = gcry_sexp_nth_data (sexp, 0, &datalen);
   if (!data)
     {
@@ -1893,49 +1908,17 @@ ssh_key_to_blob (gcry_sexp_t sexp, int with_secret,
   /* Write the ssh algorithm identifier.  */
   if ((key_spec.flags & SPEC_FLAG_IS_ECDSA))
     {
-      /* Parse the "curve" parameter.  We currently expect the curve
-         name for ECC and not the parameters of the curve.  This can
-         easily be changed but then we need to find the curve name
-         from the parameters using gcry_pk_get_curve.  */
-      const char *mapped;
-      const char *sshname;
-
-      gcry_sexp_release (value_pair);
-      value_pair = gcry_sexp_find_token (value_list, "curve", 5);
-      if (!value_pair)
-	{
-	  err = gpg_error (GPG_ERR_INV_CURVE);
-	  goto out;
-        }
-      curve_name = gcry_sexp_nth_string (value_pair, 1);
-      if (!curve_name)
-	{
-	  err = gpg_error (GPG_ERR_INV_CURVE); /* (Or out of core.)  */
-	  goto out;
-        }
+      /* Map the curve name to the ssh name.  */
+      const char *name, *sshname, *canon_name;
 
-      /* Fixme: The mapping should be done by using gcry_pk_get_curve
-         et al to iterate over all name aliases.  */
-      if (!strcmp (curve_name, "NIST P-256"))
-        mapped = "nistp256";
-      else if (!strcmp (curve_name, "NIST P-384"))
-        mapped = "nistp384";
-      else if (!strcmp (curve_name, "NIST P-521"))
-        mapped = "nistp521";
-      else
-        mapped = NULL;
-      if (mapped)
+      name = gcry_pk_get_curve (sexp, 0, NULL);
+      if (!name)
         {
-          xfree (curve_name);
-          curve_name = xtrystrdup (mapped);
-          if (!curve_name)
-            {
-              err = gpg_error_from_syserror ();
-              goto out;
-            }
+          err = gpg_error (GPG_ERR_INV_CURVE);
+          goto out;
         }
 
-      sshname = ssh_identifier_from_curve_name (curve_name);
+      sshname = ssh_identifier_from_curve_name (name, &canon_name);
       if (!sshname)
         {
           err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
@@ -1944,7 +1927,7 @@ ssh_key_to_blob (gcry_sexp_t sexp, int with_secret,
       err = stream_write_cstring (stream, sshname);
       if (err)
         goto out;
-      err = stream_write_cstring (stream, curve_name);
+      err = stream_write_cstring (stream, canon_name);
       if (err)
         goto out;
     }
@@ -2017,7 +2000,6 @@ ssh_key_to_blob (gcry_sexp_t sexp, int with_secret,
  out:
   gcry_sexp_release (value_list);
   gcry_sexp_release (value_pair);
-  xfree (curve_name);
   es_fclose (stream);
   es_free (blob);
 
@@ -2076,7 +2058,7 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret,
   ssh_key_type_spec_t spec;
   gcry_mpi_t *mpi_list = NULL;
   const char *elems;
-  char *curve_name = NULL;
+  const char *curve_name = NULL;
 
 
   err = stream_read_cstring (stream, &key_type);
@@ -2199,34 +2181,19 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret,
        * certificate.
        */
       unsigned char *buffer;
-      const char *mapped;
 
       err = stream_read_string (cert? cert : stream, 0, &buffer, NULL);
       if (err)
         goto out;
-      curve_name = buffer;
-      /* Fixme: Check that curve_name matches the keytype.  */
-      /* Because Libgcrypt < 1.6 has no support for the "nistpNNN"
-         curve names, we need to translate them here to Libgcrypt's
-         native names.  */
-      if (!strcmp (curve_name, "nistp256"))
-        mapped = "NIST P-256";
-      else if (!strcmp (curve_name, "nistp384"))
-        mapped = "NIST P-384";
-      else if (!strcmp (curve_name, "nistp521"))
-        mapped = "NIST P-521";
-      else
-        mapped = NULL;
-      if (mapped)
+      /* Get the canonical name.  Should be the same as the read
+       * string but we use this mapping to validate that name.  */
+      if (!ssh_identifier_from_curve_name (buffer, &curve_name))
         {
-          xfree (curve_name);
-          curve_name = xtrystrdup (mapped);
-          if (!curve_name)
-            {
-              err = gpg_error_from_syserror ();
-              goto out;
-            }
+          err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
+          xfree (buffer);
+          goto out;
         }
+      xfree (buffer);
 
       err = ssh_receive_mpint_list (stream, secret, &spec, cert, &mpi_list);
       if (err)
@@ -2294,7 +2261,6 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret,
  out:
   es_fclose (cert);
   mpint_list_free (mpi_list);
-  xfree (curve_name);
   xfree (key_type);
   xfree (comment);
 
@@ -2642,6 +2608,8 @@ ssh_handler_request_identities (ctrl_t ctrl,
             continue;
 
           err = ssh_send_key_public (key_blobs, key_public, cardsn);
+          if (err && opt.verbose)
+            gcry_log_debugsxp ("pubkey", key_public);
           gcry_sexp_release (key_public);
           key_public = NULL;
           xfree (cardsn);
@@ -2717,6 +2685,8 @@ ssh_handler_request_identities (ctrl_t ctrl,
     }
   else
     {
+      log_error ("ssh request identities failed: %s <%s>\n",
+                 gpg_strerror (err), gpg_strsource (err));
       ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
     }
 

commit f5d3b982e44c5cfc60e9936020102a598b635187
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Jan 22 10:06:15 2019 +0100

    gpg: Stop early when trying to create a primary Elgamal key.
    
    * g10/misc.c (openpgp_pk_test_algo2): Add extra check.
    --
    
    The problem is that --key-gen --batch with a parameter file didn't
    detect that Elgamal is not capable of signing and so an error was only
    triggered at the time the self-signature was created.  See the code
    comment for details.
    
    GnuPG-bug-id: 4329
    Signed-off-by: Werner Koch <wk at gnupg.org>
    (cherry picked from commit f97dc55ff1b041071bc3cbe98aa761bf77bb7ac8)

diff --git a/g10/misc.c b/g10/misc.c
index 9780969..7acf469 100644
--- a/g10/misc.c
+++ b/g10/misc.c
@@ -644,6 +644,13 @@ openpgp_pk_test_algo2 (pubkey_algo_t algo, unsigned int use)
   if (!ga)
     return gpg_error (GPG_ERR_PUBKEY_ALGO);
 
+  /* Elgamal in OpenPGP used to support signing and Libgcrypt still
+   * does.  However, we removed the signing capability from gpg ages
+   * ago.  This function should reflect this so that errors are thrown
+   * early and not only when we try to sign using Elgamal.  */
+  if (ga == GCRY_PK_ELG && (use & (PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG)))
+    return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
+
   /* Now check whether Libgcrypt has support for the algorithm.  */
   return gcry_pk_algo_info (ga, GCRYCTL_TEST_ALGO, NULL, &use_buf);
 }

-----------------------------------------------------------------------

Summary of changes:
 agent/command-ssh.c | 138 ++++++++++++++++++++--------------------------------
 doc/gpg.texi        |  30 ++----------
 g10/misc.c          |   7 +++
 po/Makevars         |   1 +
 scd/apdu.c          |  30 ++++++++----
 scd/apdu.h          |   2 +-
 scd/app-common.h    |   5 +-
 scd/app-nks.c       |   7 ++-
 scd/app-openpgp.c   |   4 ++
 scd/app.c           |   2 +-
 scd/command.c       |  39 +++++++++++++--
 scd/iso7816.c       |  67 ++++++++++++++++++++-----
 scd/iso7816.h       |   9 +++-
 scd/scdaemon.h      |   3 ++
 14 files changed, 202 insertions(+), 142 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list