[git] GnuPG - branch, master, updated. gnupg-2.2.7-365-ga1cb4a9

by Werner Koch cvs at cvs.gnupg.org
Fri Feb 8 11:58:52 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, master has been updated
       via  a1cb4a940f308ba21ecc002b044efccf0c547784 (commit)
       via  b349adc5c0d00d2fc405a45bd078f1580b5610cc (commit)
       via  e2f18023b3b3b7e55b35218f65e37448d1011172 (commit)
      from  b79bc877f2ad4d08e7de377cf4bf616b981b3c5f (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 a1cb4a940f308ba21ecc002b044efccf0c547784
Author: Werner Koch <wk at gnupg.org>
Date:   Fri Feb 8 11:58:27 2019 +0100

    card: Make "generate" work for PIV cards.
    
    * tools/card-call-scd.c (scd_genkey_cb): Make createtime optional.
    (scd_genkey_cb):  Ditto.  Add arg algo.
    * tools/gpg-card-tool.c (cmd_generate): Add options and factor card
    specific code out to ...
    (generate_openpgp, generate_generic): new functions.
    --
    
    This patch keeps the interactive OpenPGP mode but adds a pure command
    line mode for other cards; in particular PIV cards.  What we still
    need to do is:
     a) Add an interactive mode for PIV cards
     b) Add a command line mode for OpenPGP cards.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c
index 0d6dabf..97fb6d9 100644
--- a/tools/card-call-scd.c
+++ b/tools/card-call-scd.c
@@ -202,7 +202,7 @@ app_type_string (app_type_t app_type)
     case APP_TYPE_OPENPGP:   result = "OpenPGP"; break;
     case APP_TYPE_NKS:       result = "NetKey"; break;
     case APP_TYPE_DINSIG:    result = "DINSIG"; break;
-    case APP_TYPE_P15:       result = "PKCS#15"; break;
+    case APP_TYPE_P15:       result = "P15"; break;
     case APP_TYPE_GELDKARTE: result = "Geldkarte"; break;
     case APP_TYPE_SC_HSM:    result = "SC-HSM"; break;
     case APP_TYPE_PIV:       result = "PIV"; break;
@@ -1174,7 +1174,8 @@ scd_genkey_cb (void *opaque, const char *line)
 
  if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
     {
-      *createtime = (u32)strtoul (line, NULL, 10);
+      if (createtime)
+        *createtime = (u32)strtoul (line, NULL, 10);
     }
   else if (keywordlen == 8 && !memcmp (keyword, "PROGRESS", keywordlen))
     {
@@ -1190,7 +1191,7 @@ scd_genkey_cb (void *opaque, const char *line)
  * SCDEAMON.  On success, creation time is stored back to
  * CREATETIME.  */
 gpg_error_t
-scd_genkey (int keyno, int force, u32 *createtime)
+scd_genkey (const char *keyref, int force, const char *algo, u32 *createtime)
 {
   gpg_error_t err;
   char line[ASSUAN_LINELENGTH];
@@ -1203,15 +1204,17 @@ scd_genkey (int keyno, int force, u32 *createtime)
   if (err)
     return err;
 
-  if (*createtime)
+  if (createtime && *createtime)
     epoch2isotime (tbuf, *createtime);
   else
     *tbuf = 0;
 
-  snprintf (line, sizeof line, "SCD GENKEY %s%s %s %d",
+  snprintf (line, sizeof line, "SCD GENKEY %s%s %s %s%s -- %s",
             *tbuf? "--timestamp=":"", tbuf,
             force? "--force":"",
-            keyno);
+            algo? "--algo=":"",
+            algo? algo:"",
+            keyref);
 
   dfltparm.ctx = agent_ctx;
   err = assuan_transact (agent_ctx, line,
diff --git a/tools/card-tool.h b/tools/card-tool.h
index c121e88..9daf7e4 100644
--- a/tools/card-tool.h
+++ b/tools/card-tool.h
@@ -208,7 +208,8 @@ gpg_error_t scd_writecert (const char *certidstr,
                            const unsigned char *certdata, size_t certdatalen);
 gpg_error_t scd_writekey (int keyno,
                           const unsigned char *keydata, size_t keydatalen);
-gpg_error_t scd_genkey (int keyno, int force, u32 *createtime);
+gpg_error_t scd_genkey (const char *keyref, int force, const char *algo,
+                        u32 *createtime);
 gpg_error_t scd_serialno (char **r_serialno, const char *demand);
 gpg_error_t scd_readcert (const char *certidstr,
                           void **r_buf, size_t *r_buflen);
diff --git a/tools/gpg-card-tool.c b/tools/gpg-card-tool.c
index 71ce13f..93153b1 100644
--- a/tools/gpg-card-tool.c
+++ b/tools/gpg-card-tool.c
@@ -1722,7 +1722,8 @@ cmd_forcesig (card_info_t info)
 }
 
 
-/* Helper for cmd_generate.  Noe that either 0 or 1 is stored at
+

+/* Helper for cmd_generate_openpgp.  Noe that either 0 or 1 is stored at
  * FORCED_CHV1. */
 static gpg_error_t
 check_pin_for_key_operation (card_info_t info, int *forced_chv1)
@@ -1754,7 +1755,7 @@ check_pin_for_key_operation (card_info_t info, int *forced_chv1)
 }
 
 
-/* Helper for cmd_generate.  */
+/* Helper for cmd_generate_openpgp.  */
 static void
 restore_forced_chv1 (int *forced_chv1)
 {
@@ -1775,8 +1776,9 @@ restore_forced_chv1 (int *forced_chv1)
 }
 
 
+/* Implementation of cmd_generate for OpenPGP cards.  */
 static gpg_error_t
-cmd_generate (card_info_t info)
+generate_openpgp (card_info_t info)
 {
   gpg_error_t err;
   int forced_chv1 = -1;
@@ -1784,18 +1786,6 @@ cmd_generate (card_info_t info)
   char *answer = NULL;
   key_info_t kinfo1, kinfo2, kinfo3;
 
-  if (!info)
-    return print_help
-      ("GENERATE\n\n"
-       "Menu to generate a new keys.",
-       APP_TYPE_OPENPGP, 0);
-
-  if (info->apptype != APP_TYPE_OPENPGP)
-    {
-      log_info ("Note: This is an OpenPGP only command.\n");
-      return gpg_error (GPG_ERR_NOT_SUPPORTED);
-    }
-
   if (info->extcap.ki)
     {
       xfree (answer);
@@ -1811,7 +1801,6 @@ cmd_generate (card_info_t info)
   else
     want_backup = 0;
 
-
   kinfo1 = find_kinfo (info, "OPENPGP.1");
   kinfo2 = find_kinfo (info, "OPENPGP.2");
   kinfo3 = find_kinfo (info, "OPENPGP.3");
@@ -1860,6 +1849,7 @@ cmd_generate (card_info_t info)
    * gpg.  We might also first create the keys on the card and then
    * tell gpg to use them to create the OpenPGP keyblock. */
   /* generate_keypair (ctrl, 1, NULL, info.serialno, want_backup); */
+  (void)want_backup;
   err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
 
  leave:
@@ -1869,6 +1859,126 @@ cmd_generate (card_info_t info)
 }
 
 
+/* Generic implementation of cmd_generate.  */
+static gpg_error_t
+generate_generic (card_info_t info, const char *keyref, int force,
+                  const char *algo)
+{
+  gpg_error_t err;
+
+  (void)info;
+
+  err = scd_genkey (keyref, force, algo, NULL);
+
+  return err;
+}
+
+
+static gpg_error_t
+cmd_generate (card_info_t info, char *argstr)
+{
+  static char * const valid_algos[] =
+    { "rsa2048", "rsa3072", "rsa4096",
+      "nistp256", "nistp384", "nistp521",
+      "ed25519", "cv25519",
+      NULL
+    };
+  gpg_error_t err;
+  int opt_force;
+  char *opt_algo = NULL; /* Malloced.  */
+  char *keyref_buffer = NULL;  /* Malloced.  */
+  char *keyref;          /* Points into argstr or keyref_buffer.  */
+  int i;
+
+  if (!info)
+    return print_help
+      ("GENERATE [--force] [--algo=ALGO] KEYREF\n\n"
+       "Create a new key on a card.  For OpenPGP cards are menu is used\n"
+       "and KEYREF is ignored.  Use --force to overwrite an existing key.",
+       APP_TYPE_OPENPGP, APP_TYPE_PIV, 0);
+
+  if (opt.interactive || opt.verbose)
+    log_info (_("%s card no. %s detected\n"),
+              app_type_string (info->apptype),
+              info->dispserialno? info->dispserialno : info->serialno);
+
+  opt_force = has_leading_option (argstr, "--force");
+  err = get_option_value (argstr, "--algo", &opt_algo);
+  if (err)
+    goto leave;
+  argstr = skip_options (argstr);
+
+  keyref = argstr;
+  if ((argstr = strchr (keyref, ' ')))
+    {
+      *argstr++ = 0;
+      trim_spaces (keyref);
+      trim_spaces (argstr);
+    }
+  else /* Let argstr point to an empty string.  */
+    argstr = keyref + strlen (keyref);
+
+  if (!*keyref)
+    keyref = NULL;
+
+  if (*argstr)
+    {
+      /* Extra arguments found.  */
+      err = gpg_error (GPG_ERR_INV_ARG);
+      goto leave;
+    }
+
+  if (opt_algo)
+    {
+      for (i=0; valid_algos[i]; i++)
+        if (!strcmp (valid_algos[i], opt_algo))
+          break;
+      if (!valid_algos[i])
+        {
+          err = gpg_error (GPG_ERR_PUBKEY_ALGO);
+          log_info ("Invalid algorithm '%s' given.  Use one:\n", opt_algo);
+          for (i=0; valid_algos[i]; i++)
+            if (!(i%5))
+              log_info ("  %s%s", valid_algos[i], valid_algos[i+1]?",":".");
+            else
+              log_printf (" %s%s", valid_algos[i], valid_algos[i+1]?",":".");
+          log_info ("Note that the card may not support all of them.\n");
+          goto leave;
+        }
+    }
+
+  /* Upcase the keyref; if it misses the cardtype, prepend it.  */
+  if (keyref)
+    {
+      if (!strchr (keyref, '.'))
+        keyref_buffer = xstrconcat (app_type_string (info->apptype), ".",
+                                    keyref, NULL);
+      else
+        keyref_buffer = xstrdup (keyref);
+      ascii_strupr (keyref_buffer);
+      keyref = keyref_buffer;
+    }
+
+  /* Divert to dedicated functions.  */
+  if (info->apptype == APP_TYPE_OPENPGP)
+    {
+      if (opt_force || opt_algo || keyref)
+        log_info ("Note: Options are ignored for OpenPGP cards.\n");
+      err = generate_openpgp (info);
+    }
+  else if (!keyref)
+    err = gpg_error (GPG_ERR_INV_ID);
+  else
+    err = generate_generic (info, keyref, opt_force, opt_algo);
+
+ leave:
+  xfree (opt_algo);
+  xfree (keyref_buffer);
+  return err;
+}
+
+
+

 /* Sub-menu to change a PIN.  The presented options may depend on the
  * the ALLOW_ADMIN flag.  */
 static gpg_error_t
@@ -2572,6 +2682,8 @@ ask_card_keyattr (int keyno, const struct key_attr *current,
           curve = current->curve;
         }
 
+      (void)curve;
+      (void)algo;
       err = GPG_ERR_NOT_IMPLEMENTED;
       goto leave;
       /* FIXME: We need to mve the ask_cure code out to common or
@@ -2929,7 +3041,7 @@ dispatch_command (card_info_t info, const char *orig_command)
     case cmdWRITECERT:    err = cmd_writecert (info, argstr); break;
     case cmdREADCERT:     err = cmd_readcert (info, argstr); break;
     case cmdFORCESIG:     err = cmd_forcesig (info); break;
-    case cmdGENERATE:     err = cmd_generate (info); break;
+    case cmdGENERATE:     err = cmd_generate (info, argstr); break;
     case cmdPASSWD:       err = cmd_passwd (info, 1, argstr); break;
     case cmdUNBLOCK:      err = cmd_unblock (info); break;
     case cmdFACTORYRESET: err = cmd_factoryreset (info); break;
@@ -3195,7 +3307,7 @@ interactive_loop (void)
         case cmdWRITECERT: err = cmd_writecert (info, argstr); break;
         case cmdREADCERT:  err = cmd_readcert (info, argstr); break;
         case cmdFORCESIG:  err = cmd_forcesig (info); break;
-        case cmdGENERATE:  err = cmd_generate (info); break;
+        case cmdGENERATE:  err = cmd_generate (info, argstr); break;
         case cmdPASSWD:    err = cmd_passwd (info, allow_admin, argstr); break;
         case cmdUNBLOCK:   err = cmd_unblock (info); break;
         case cmdFACTORYRESET:

commit b349adc5c0d00d2fc405a45bd078f1580b5610cc
Author: Werner Koch <wk at gnupg.org>
Date:   Fri Feb 8 11:53:34 2019 +0100

    scd: Allow generating ECC curves on PIV cards.
    
    * scd/app-piv.c (genkey_parse_ecc): New.
    (get_keygrip_by_tag): Call that one.
    (do_readkey): Call that one.
    * scd/command.c (cmd_genkey): Add option --algo.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/scd/app-piv.c b/scd/app-piv.c
index f4eb918..4387b3a 100644
--- a/scd/app-piv.c
+++ b/scd/app-piv.c
@@ -178,6 +178,8 @@ static gpg_error_t get_keygrip_by_tag (app_t app, unsigned int tag,
                                        char **r_keygripstr, int *got_cert);
 static gpg_error_t genkey_parse_rsa (const unsigned char *data, size_t datalen,
                                      gcry_sexp_t *r_sexp);
+static gpg_error_t genkey_parse_ecc (const unsigned char *data, size_t datalen,
+                                     int mechanism, gcry_sexp_t *r_sexp);
 
 
 
@@ -1144,6 +1146,9 @@ get_keygrip_by_tag (app_t app, unsigned int tag,
     {
       if (mechanism == PIV_ALGORITHM_RSA)
         err = genkey_parse_rsa (certbuf, certbuflen, &s_pkey);
+      else if (mechanism == PIV_ALGORITHM_ECC_P256
+               || mechanism == PIV_ALGORITHM_ECC_P384)
+        err = genkey_parse_ecc (certbuf, certbuflen, mechanism, &s_pkey);
       else
         err = gpg_error (GPG_ERR_PUBKEY_ALGO);
       if (err)
@@ -1308,6 +1313,9 @@ do_readkey (app_t app, int advanced, const char *keyrefstr,
   /* Convert the public key into the expected s-expression.  */
   if (mechanism == PIV_ALGORITHM_RSA)
     err = genkey_parse_rsa (cert, certlen, &s_pkey);
+  else if (mechanism == PIV_ALGORITHM_ECC_P256
+           || mechanism == PIV_ALGORITHM_ECC_P384)
+    err = genkey_parse_ecc (cert, certlen, mechanism, &s_pkey);
   else
     err = gpg_error (GPG_ERR_PUBKEY_ALGO);
   if (err)
@@ -2155,6 +2163,48 @@ genkey_parse_rsa (const unsigned char *data, size_t datalen,
 }
 
 
+/* Parse an ECC response object, consisting of the content of tag
+ * 0x7f49, into a gcrypt s-expression object and store that R_SEXP.
+ * On error NULL is stored at R_SEXP.  MECHANISM specifies the
+ * curve.  */
+static gpg_error_t
+genkey_parse_ecc (const unsigned char *data, size_t datalen, int mechanism,
+                  gcry_sexp_t *r_sexp)
+{
+  gpg_error_t err;
+  const unsigned char *ecc_q;
+  size_t ecc_qlen;
+  const char *curve;
+
+  *r_sexp = NULL;
+
+  ecc_q = find_tlv (data, datalen, 0x0086, &ecc_qlen);
+  if (!ecc_q)
+    {
+      log_error (_("response does not contain the EC public key\n"));
+      err = gpg_error (GPG_ERR_CARD);
+      goto leave;
+    }
+
+  if (mechanism == PIV_ALGORITHM_ECC_P256)
+    curve = "nistp256";
+  else if (mechanism == PIV_ALGORITHM_ECC_P384)
+    curve = "nistp384";
+  else
+    {
+      err = gpg_error (GPG_ERR_BUG); /* Call with wrong parameters.  */
+      goto leave;
+    }
+
+
+  err = gcry_sexp_build (r_sexp, NULL, "(public-key(ecc(curve%s)(q%b)))",
+                         curve, (int)ecc_qlen, ecc_q);
+
+ leave:
+  return err;
+}
+
+
 /* Create a new keypair for KEYREF.  If KEYTYPE is NULL a default
  * keytype is selected, else it may be one of the strings:
  *  "rsa2048", "nistp256, or "nistp384".
@@ -2303,6 +2353,9 @@ do_writecert (app_t app, ctrl_t ctrl,
 
   /* FIXME: Check that the authentication has already been done.  */
 
+  /* FIXME: Check that the public key parameters from the certificate
+   * match an already stored key.  */
+
   flush_cached_data (app, dobj->tag);
   err = put_data (app->slot, dobj->tag,
                   (int)0x70, (size_t)certlen, cert,/* Certificate */
diff --git a/scd/command.c b/scd/command.c
index 127fb5d..237faf0 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -1126,10 +1126,10 @@ cmd_writekey (assuan_context_t ctx, char *line)
 
 
 static const char hlp_genkey[] =
-  "GENKEY [--force] [--timestamp=<isodate>] <no>\n"
+  "GENKEY [--force] [--timestamp=<isodate>] <keyref>\n"
   "\n"
-  "Generate a key on-card identified by NO, which is application\n"
-  "specific.  Return values are application specific.  For OpenPGP\n"
+  "Generate a key on-card identified by <keyref>, which is application\n"
+  "specific.  Return values are also application specific.  For OpenPGP\n"
   "cards 3 status lines are returned:\n"
   "\n"
   "  S KEY-FPR  <hexstring>\n"
@@ -1154,10 +1154,12 @@ static gpg_error_t
 cmd_genkey (assuan_context_t ctx, char *line)
 {
   ctrl_t ctrl = assuan_get_pointer (ctx);
-  int rc;
-  char *keyno;
+  gpg_error_t err;
+  char *keyref_buffer = NULL;
+  char *keyref;
   int force;
   const char *s;
+  char *opt_algo = NULL;
   time_t timestamp;
 
   force = has_option (line, "--force");
@@ -1173,30 +1175,38 @@ cmd_genkey (assuan_context_t ctx, char *line)
   else
     timestamp = 0;
 
+  err = get_option_value (line, "--algo", &opt_algo);
+  if (err)
+    goto leave;
 
   line = skip_options (line);
   if (!*line)
     return set_error (GPG_ERR_ASS_PARAMETER, "no key number given");
-  keyno = line;
+  keyref = line;
   while (*line && !spacep (line))
     line++;
   *line = 0;
 
-  if ((rc = open_card (ctrl)))
-    return rc;
+  if ((err = open_card (ctrl)))
+    goto leave;
 
   if (!ctrl->app_ctx)
     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
 
-  keyno = xtrystrdup (keyno);
-  if (!keyno)
-    return out_of_core ();
-  rc = app_genkey (ctrl->app_ctx, ctrl, keyno, NULL,
-                   force? APP_GENKEY_FLAG_FORCE : 0,
-                   timestamp, pin_cb, ctx);
-  xfree (keyno);
+  keyref = keyref_buffer = xtrystrdup (keyref);
+  if (!keyref)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  err = app_genkey (ctrl->app_ctx, ctrl, keyref, opt_algo,
+                    force? APP_GENKEY_FLAG_FORCE : 0,
+                    timestamp, pin_cb, ctx);
 
-  return rc;
+ leave:
+  xfree (keyref_buffer);
+  xfree (opt_algo);
+  return err;
 }
 
 

commit e2f18023b3b3b7e55b35218f65e37448d1011172
Author: Werner Koch <wk at gnupg.org>
Date:   Fri Feb 8 09:32:55 2019 +0100

    common: New functions get_option_value and ascii_strupr.
    
    * common/server-help.c (get_option_value): New.
    * common/stringhelp.c (ascii_strupr): New.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/common/server-help.c b/common/server-help.c
index 53a888a..e5a69e0 100644
--- a/common/server-help.c
+++ b/common/server-help.c
@@ -30,8 +30,22 @@
 #include <config.h>
 #include <string.h>
 
-#include "server-help.h"
 #include "util.h"
+#include "server-help.h"
+
+
+static GPGRT_INLINE gpg_error_t
+my_error (int e)
+{
+  return gpg_err_make (default_errsource, (e));
+}
+
+static GPGRT_INLINE gpg_error_t
+my_error_from_syserror (void)
+{
+  return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+}
+
 
 /* Skip over options in LINE.
 
@@ -114,6 +128,40 @@ has_option_name (const char *line, const char *name)
 }
 
 
+/* Parse an option with the format "--NAME=VALUE" which must occur in
+ * LINE before a double-dash.  LINE is written to but not modified by
+ * this function.  If the option is found and has a value the value is
+ * stored as a malloced string at R_VALUE.  If the option was not
+ * found or an error occurred NULL is stored there.  Note that
+ * currently the value must be a string without any space; we may
+ * eventually update this function to allow for a quoted value.  */
+gpg_error_t
+get_option_value (char *line, const char *name, char **r_value)
+{
+  char *p, *pend;
+  int c;
+
+  *r_value = NULL;
+
+  p = (char*)has_option_name (line, name);
+  if (!p || p >= skip_options (line))
+    return 0;
+
+  if (*p != '=' || !p[1] || spacep (p+1))
+    return my_error (GPG_ERR_INV_ARG);
+  p++;
+  for (pend = p; *pend && !spacep (pend); pend++)
+    ;
+  c = *pend;
+  *pend = 0;
+  *r_value = xtrystrdup (p);
+  *pend = c;
+  if (!p)
+    return my_error_from_syserror ();
+  return 0;
+}
+
+
 /* Return a pointer to the argument of the option with NAME.  If such
    an option is not given, NULL is returned. */
 char *
diff --git a/common/server-help.h b/common/server-help.h
index 9e3d7ad..9d2f4cf 100644
--- a/common/server-help.h
+++ b/common/server-help.h
@@ -55,6 +55,14 @@ int has_leading_option (const char *line, const char *name);
    or a space.  */
 const char *has_option_name (const char *line, const char *name);
 
+/* Same as has_option_name but ignores all options after a "--" and
+ * does not return a const char ptr.  */
+char *has_leading_option_name (char *line, const char *name);
+
+/* Parse an option with the format "--NAME=VALUE" and return the value
+ * as a malloced string.  */
+gpg_error_t get_option_value (char *line, const char *name, char **r_value);
+
 /* Return a pointer to the argument of the option with NAME.  If such
    an option is not given, NULL is returned. */
 char *option_value (const char *line, const char *name);
diff --git a/common/stringhelp.c b/common/stringhelp.c
index 751e571..dd17116 100644
--- a/common/stringhelp.c
+++ b/common/stringhelp.c
@@ -810,6 +810,19 @@ ascii_strlwr (char *s)
   return s;
 }
 
+/* Upcase all ASCII characters in S.  */
+char *
+ascii_strupr (char *s)
+{
+  char *p = s;
+
+  for (p=s; *p; p++ )
+    if (isascii (*p) && *p >= 'a' && *p <= 'z')
+      *p &= ~0x20;
+
+  return s;
+}
+
 int
 ascii_strcasecmp( const char *a, const char *b )
 {
diff --git a/common/stringhelp.h b/common/stringhelp.h
index 5b07af9..7df6c76 100644
--- a/common/stringhelp.h
+++ b/common/stringhelp.h
@@ -76,6 +76,7 @@ int ascii_islower (int c);
 int ascii_toupper (int c);
 int ascii_tolower (int c);
 char *ascii_strlwr (char *s);
+char *ascii_strupr (char *s);
 int ascii_strcasecmp( const char *a, const char *b );
 int ascii_strncasecmp (const char *a, const char *b, size_t n);
 int ascii_memcasecmp( const void *a, const void *b, size_t n );

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

Summary of changes:
 common/server-help.c  |  50 ++++++++++++++++-
 common/server-help.h  |   8 +++
 common/stringhelp.c   |  13 +++++
 common/stringhelp.h   |   1 +
 scd/app-piv.c         |  53 ++++++++++++++++++
 scd/command.c         |  42 ++++++++------
 tools/card-call-scd.c |  15 +++--
 tools/card-tool.h     |   3 +-
 tools/gpg-card-tool.c | 148 ++++++++++++++++++++++++++++++++++++++++++++------
 9 files changed, 291 insertions(+), 42 deletions(-)


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




More information about the Gnupg-commits mailing list