[git] GnuPG - branch, master, updated. gnupg-2.2.7-357-gb5b1f72

by Werner Koch cvs at cvs.gnupg.org
Wed Feb 6 20:48:22 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  b5b1f721582df9d0379cb68b4faeceed32a56e49 (commit)
       via  9a9cb0257aebb1480b999fdf9d90904083eb8e3c (commit)
       via  c26af8ac263ea006ed32e110a09271e4bfbf1f37 (commit)
      from  6c581cc468d7a1b860632b7a465d71224c6e4999 (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 b5b1f721582df9d0379cb68b4faeceed32a56e49
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Feb 6 20:47:07 2019 +0100

    scd: Add genkey command to app-piv (rsa-only)
    
    * scd/app-piv.c (struct genkey_result_s): new.
    (struct app_local_s): add member genkey_results.
    (do_deinit): Free that one.
    (flush_cached_data): Extend to delete all items.
    (keyref_from_dobj): New.
    (do_readkey): New.
    (do_auth): Use keyref_from_dobj.
    (does_key_exist): New.
    (genkey_parse_rsa): New.
    (do_genkey): New.
    --
    
    We need to extend the GENKEY in command.c to support other algos.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/scd/app-piv.c b/scd/app-piv.c
index 42f16de..cfc4a27 100644
--- a/scd/app-piv.c
+++ b/scd/app-piv.c
@@ -38,6 +38,7 @@
  *   | Unblock PIN  |     |     | yes | New PIN required             |
  *   |---------------------------------------------------------------|
  *   (9B indicates the 24 byte PIV Card Application Administration Key)
+ *
  */
 
 #include <config.h>
@@ -152,11 +153,22 @@ struct cache_s {
 };
 
 
+/* A cache item used by genkey.  */
+struct genkey_result_s {
+  struct genkey_result_s *next;
+  int keyref;
+  gcry_sexp_t s_pkey;
+};
+
+
 /* Object with application specific data.  */
 struct app_local_s {
   /* A linked list with cached DOs.  */
   struct cache_s *cache;
 
+  /* A list with results from recent genkey operations.  */
+  struct genkey_result_s *genkey_results;
+
   /* Various flags.  */
   struct
   {
@@ -181,12 +193,19 @@ do_deinit (app_t app)
   if (app && app->app_local)
     {
       struct cache_s *c, *c2;
+      struct genkey_result_s *gr, *gr2;
 
       for (c = app->app_local->cache; c; c = c2)
         {
           c2 = c->next;
           xfree (c);
         }
+      for (gr = app->app_local->genkey_results; gr; gr = gr2)
+        {
+          gr2 = gr->next;
+          gcry_sexp_release (gr->s_pkey);
+          xfree (gr);
+        }
 
       xfree (app->app_local);
       app->app_local = NULL;
@@ -284,14 +303,15 @@ get_cached_data (app_t app, int tag,
 }
 
 
-/* Remove data object described by TAG from the cache.  */
+/* Remove data object described by TAG from the cache.  If TAG is 0
+ * all cache iterms are flushed.  */
 static void
 flush_cached_data (app_t app, int tag)
 {
   struct cache_s *c, *cprev;
 
   for (c=app->app_local->cache, cprev=NULL; c; cprev=c, c = c->next)
-    if (c->tag == tag)
+    if (c->tag == tag || !tag)
       {
         if (cprev)
           cprev->next = c->next;
@@ -860,7 +880,7 @@ do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
 }
 
 
-/* Core of do-readcert which fetches the certificate based on the
+/* Core of do_readcert which fetches the certificate based on the
  * given tag and returns it in a freshly allocated buffer stored at
  * R_CERT and the length of the certificate stored at R_CERTLEN.  */
 static gpg_error_t
@@ -1010,6 +1030,17 @@ find_dobj_by_keyref (app_t app, const char *keyref)
 }
 
 
+/* Return the keyref from DOBJ as an integer.  If it does not exist,
+ * return -1.  */
+static int
+keyref_from_dobj (data_object_t dobj)
+{
+  if (!dobj || !hexdigitp (dobj->keyref) || !hexdigitp (dobj->keyref+1))
+    return -1;
+  return xtoi_2 (dobj->keyref);
+}
+
+
 /* Read a certificate from the card and returned in a freshly
  * allocated buffer stored at R_CERT and the length of the certificate
  * stored at R_CERTLEN.  CERTID is either the OID of the cert's
@@ -1031,6 +1062,70 @@ do_readcert (app_t app, const char *certid,
 }
 
 
+/* Return a public key in a freshly allocated buffer.  This will only
+ * work for a freshly generated key as long as no reset of the
+ * application has been performed.  This is because we return a cached
+ * result from key generation.  If no cached result is available, the
+ * error GPG_ERR_UNSUPPORTED_OPERATION is returned so that the higher
+ * layer can then to get the key by reading the matching certificate.
+ * On success a canonical encoded S-expression with the public key is
+ * stored at (R_PK,R_PKLEN); the caller must release that buffer.  On
+ * error R_PK and R_PKLEN are not changed and an error code is
+ * returned.
+ */
+static gpg_error_t
+do_readkey (app_t app, int advanced, const char *keyrefstr,
+            unsigned char **r_pk, size_t *r_pklen)
+{
+  gpg_error_t err;
+  data_object_t dobj;
+  int keyref;
+  struct genkey_result_s *gres;
+  unsigned char *pk = NULL;
+  size_t pklen;
+
+  dobj = find_dobj_by_keyref (app, keyrefstr);
+  if ((keyref = keyref_from_dobj (dobj)) == -1)
+    {
+      err = gpg_error (GPG_ERR_INV_ID);
+      goto leave;
+    }
+  for (gres = app->app_local->genkey_results; gres; gres = gres->next)
+    if (gres->keyref == keyref)
+      break;
+  if (!gres || !gres->s_pkey)
+    {
+      err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+      goto leave;
+    }
+
+  err = make_canon_sexp (gres->s_pkey, &pk, &pklen);
+  if (err)
+    goto leave;
+  if (advanced)
+    {
+      /* FIXME: How ugly - we should move that to command.c */
+      char *p = canon_sexp_to_string (pk, pklen);
+      if (!p)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+      xfree (pk);
+      pk = p;
+      pklen = strlen (pk);
+    }
+
+  *r_pk = pk;
+  pk = NULL;
+  *r_pklen = pklen;
+
+ leave:
+  xfree (pk);
+  return err;
+}
+
+
 /* Given a data object DOBJ return the corresponding PIV algorithm and
  * store it at R_ALGO.  The algorithm is taken from the corresponding
  * certificate or from a cache.  */
@@ -1553,12 +1648,11 @@ do_auth (app_t app, const char *keyidstr,
    * make sense for X.509 certs?  */
 
   dobj = find_dobj_by_keyref (app, keyidstr);
-  if (!dobj)
+  if ((keyref = keyref_from_dobj (dobj)) == -1)
     {
       err = gpg_error (GPG_ERR_INV_ID);
       goto leave;
     }
-  keyref = xtoi_2 (dobj->keyref);
 
   err = get_key_algorithm_by_dobj (app, dobj, &algo);
   if (err)
@@ -1714,6 +1808,260 @@ do_auth (app_t app, const char *keyidstr,
 }
 
 
+/* Check whether a key for DOBJ already exists.  We detect this by
+ * reading the certificate described by DOBJ.  If FORCE is TRUE a
+ * diagnositic will be printed but no error returned if the key
+ * already exists.  The flag GENERATING is used to select a
+ * diagnositic. */
+static gpg_error_t
+does_key_exist (app_t app, data_object_t dobj, int generating, int force)
+{
+  void *relptr;
+  unsigned char *buffer;
+  size_t buflen;
+  int found;
+
+  relptr = get_one_do (app, dobj->tag, &buffer, &buflen, NULL);
+  found = (relptr && buflen);
+  xfree (relptr);
+
+  if (found && !force)
+    {
+      log_error ("piv: %s", _("key already exists\n"));
+      return gpg_error (GPG_ERR_EEXIST);
+    }
+
+  if (found)
+    log_info ("piv: %s", _("existing key will be replaced\n"));
+  else if (generating)
+    log_info ("piv: %s", _("generating new key\n"));
+  else
+    log_info ("piv: %s", _("writing new key\n"));
+  return 0;
+}
+
+
+/* Parse an RSA response object, consisting of the content of tag
+ * 0x7f49, into a gcrypt s-expresstion object and store that R_SEXP.
+ * On error NULL is stored at R_SEXP. */
+static gpg_error_t
+genkey_parse_rsa (const unsigned char *data, size_t datalen,
+                  gcry_sexp_t *r_sexp)
+{
+  gpg_error_t err;
+  const unsigned char *m, *e;
+  unsigned char *mbuf = NULL;
+  unsigned char *ebuf = NULL;
+  size_t mlen, elen;
+
+  *r_sexp = NULL;
+
+  m = find_tlv (data, datalen, 0x0081, &mlen);
+  if (!m)
+    {
+      log_error (_("response does not contain the RSA modulus\n"));
+      err = gpg_error (GPG_ERR_CARD);
+      goto leave;
+    }
+
+  e = find_tlv (data, datalen, 0x0082, &elen);
+  if (!e)
+    {
+      log_error (_("response does not contain the RSA public exponent\n"));
+      err = gpg_error (GPG_ERR_CARD);
+      goto leave;
+    }
+
+  for (; mlen && !*m; mlen--, m++) /* Strip leading zeroes */
+    ;
+  for (; elen && !*e; elen--, e++) /* Strip leading zeroes */
+    ;
+
+  mbuf = xtrymalloc (mlen + 1);
+  if (!mbuf)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  /* Prepend numbers with a 0 if needed.  */
+  if (mlen && (*m & 0x80))
+    {
+      *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
+    memcpy (ebuf, e, elen);
+
+  err = gcry_sexp_build (r_sexp, NULL, "(public-key(rsa(n%b)(e%b)))",
+                         (int)mlen, mbuf, (int)elen, ebuf);
+
+ leave:
+  xfree (mbuf);
+  xfree (ebuf);
+  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".
+ *
+ * Supported FLAGS are:
+ *   APP_GENKEY_FLAG_FORCE   Overwrite existing key.
+ *
+ * Note that CREATETIME is not used for PIV cards.
+ *
+ * Because there seems to be no way to read the public key we need to
+ * retrieve it from a certificate.  The GnuPG system however requires
+ * the use of app_readkey to fetch the public key from the card to
+ * create the certificate; to support this we temporary store the
+ * generated public key in the local context for use by app_readkey.
+ */
+static gpg_error_t
+do_genkey (app_t app, ctrl_t ctrl, const char *keyrefstr, const char *keytype,
+           unsigned int flags, time_t createtime,
+           gpg_error_t (*pincb)(void*, const char *, char **),
+           void *pincb_arg)
+{
+  gpg_error_t err;
+  data_object_t dobj;
+  unsigned char *buffer = NULL;
+  size_t buflen;
+  int force = !!(flags & APP_GENKEY_FLAG_FORCE);
+  int mechanism;
+  time_t start_at;
+  int keyref;
+  unsigned char tmpl[5];
+  size_t tmpllen;
+  const unsigned char *keydata;
+  size_t keydatalen;
+  gcry_sexp_t s_pkey = NULL;
+  struct genkey_result_s *gres;
+
+  (void)ctrl;
+  (void)createtime;
+  (void)pincb;
+  (void)pincb_arg;
+
+  if (!keytype)
+    keytype = "rsa2048";
+
+  if (!strcmp (keytype, "rsa2048"))
+    mechanism = PIV_ALGORITHM_RSA;
+  else if (!strcmp (keytype, "nistp256"))
+    mechanism = PIV_ALGORITHM_ECC_P256;
+  else if (!strcmp (keytype, "nistp384"))
+    mechanism = PIV_ALGORITHM_ECC_P384;
+  else
+    return gpg_error (GPG_ERR_UNKNOWN_CURVE);
+
+  /* We flush the cache to increase the I/O traffic before a key
+   * generation.  This _might_ help the card to gather more entropy
+   * and is anyway a prerequisite for does_key_exist. */
+  flush_cached_data (app, 0);
+
+  /* Check whether a key already exists.  */
+  dobj = find_dobj_by_keyref (app, keyrefstr);
+  if ((keyref = keyref_from_dobj (dobj)) == -1)
+    {
+      err = gpg_error (GPG_ERR_INV_ID);
+      goto leave;
+    }
+  err = does_key_exist (app, dobj, 1, force);
+  if (err)
+    goto leave;
+
+
+  /* FIXME: Check that the authentication has already been done.  */
+
+
+
+  /* Create the key. */
+  log_info (_("please wait while key is being generated ...\n"));
+  start_at = time (NULL);
+  tmpl[0] = 0xac;
+  tmpl[1] = 3;
+  tmpl[2] = 0x80;
+  tmpl[3] = 1;
+  tmpl[4] = mechanism;
+  tmpllen = 5;
+  err = iso7816_generate_keypair (app->slot, 0, 0, keyref,
+                                  tmpl, tmpllen, 0, &buffer, &buflen);
+  if (err)
+    {
+      log_error (_("generating key failed\n"));
+      return gpg_error (GPG_ERR_CARD);
+    }
+
+  {
+    int nsecs = (int)(time (NULL) - start_at);
+    log_info (ngettext("key generation completed (%d second)\n",
+                       "key generation completed (%d seconds)\n",
+                       nsecs), nsecs);
+  }
+
+  /* Parse the result and store it as an s-expression in a dedicated
+   * cache for later retrieval by app_readkey.  */
+  keydata = find_tlv (buffer, buflen, 0x7F49, &keydatalen);
+  if (!keydata || !keydatalen)
+    {
+      err = gpg_error (GPG_ERR_CARD);
+      log_error (_("response does not contain the public key data\n"));
+      goto leave;
+    }
+
+  if (mechanism == PIV_ALGORITHM_RSA)
+    err = genkey_parse_rsa (keydata, keydatalen, &s_pkey);
+  else
+    err = gpg_error (GPG_ERR_BUG);
+  if (err)
+    goto leave;
+
+  for (gres = app->app_local->genkey_results; gres; gres = gres->next)
+    if (gres->keyref == keyref)
+      break;
+  if (!gres)
+    {
+      gres = xtrycalloc (1, sizeof *gres);
+      if (!gres)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+      gres->keyref = keyref;
+      gres->next = app->app_local->genkey_results;
+      app->app_local->genkey_results = gres;
+    }
+  else
+    gcry_sexp_release (gres->s_pkey);
+  gres->s_pkey = s_pkey;
+  s_pkey = NULL;
+
+
+ leave:
+  gcry_sexp_release (s_pkey);
+  xfree (buffer);
+  return err;
+}
+
+
 /* Select the PIV application on the card in SLOT.  This function must
  * be used before any other PIV application functions. */
 gpg_error_t
@@ -1801,12 +2149,12 @@ app_select_piv (app_t app)
   app->fnc.deinit = do_deinit;
   app->fnc.learn_status = do_learn_status;
   app->fnc.readcert = do_readcert;
-  app->fnc.readkey = NULL;
+  app->fnc.readkey = do_readkey;
   app->fnc.getattr = do_getattr;
   app->fnc.setattr = do_setattr;
   /* app->fnc.writecert = do_writecert; */
   /* app->fnc.writekey = do_writekey; */
-  /* app->fnc.genkey = do_genkey; */
+  app->fnc.genkey = do_genkey;
   /* app->fnc.sign = do_sign; */
   app->fnc.auth = do_auth;
   /* app->fnc.decipher = do_decipher; */

commit 9a9cb0257aebb1480b999fdf9d90904083eb8e3c
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Feb 6 14:07:42 2019 +0100

    scd: Make app_genkey and supporting ISO function more flexible.
    
    * scd/app.c (app_genkey): Add arg keytype.
    * scd/app-common.h (struct app_ctx_s): Fitto for the genkey member.
    * scd/command.c (cmd_genkey): Adjust for change.
    * scd/iso7816.c (do_generate_keypair): Replace arg read_only by new
    args p1 and p2.
    (iso7816_read_public_key): Adjust for this.
    (iso7816_generate_keypair): Add new args p1 and p2.
    * scd/app-openpgp.c (do_genkey): Adjust for changes.
    --
    
    The OpenPGP card creates keys according to parameters read from a data
    object.  Other cards we are about to implement require a direct
    specification of the requested keytype.  This patch implements the
    required changes.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/scd/app-common.h b/scd/app-common.h
index d8b301c..e9d167e 100644
--- a/scd/app-common.h
+++ b/scd/app-common.h
@@ -106,8 +106,8 @@ struct app_ctx_s {
                              void *pincb_arg,
                              const unsigned char *pk, size_t pklen);
     gpg_error_t (*genkey) (app_t app, ctrl_t ctrl,
-                           const char *keynostr, unsigned int flags,
-                           time_t createtime,
+                           const char *keyref, const char *keytype,
+                           unsigned int flags, time_t createtime,
                            gpg_error_t (*pincb)(void*, const char *, char **),
                            void *pincb_arg);
     gpg_error_t (*change_pin) (app_t app, ctrl_t ctrl,
@@ -178,8 +178,8 @@ gpg_error_t app_writekey (app_t app, ctrl_t ctrl,
                           void *pincb_arg,
                           const unsigned char *keydata, size_t keydatalen);
 gpg_error_t app_genkey (app_t app, ctrl_t ctrl,
-                        const char *keynostr, unsigned int flags,
-                        time_t createtime,
+                        const char *keynostr, const char *keytype,
+                        unsigned int flags, time_t createtime,
                         gpg_error_t (*pincb)(void*, const char *, char **),
                         void *pincb_arg);
 gpg_error_t app_get_challenge (app_t app, ctrl_t ctrl, size_t nbytes,
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index 72ed80a..ae87d19 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -4086,8 +4086,8 @@ do_writekey (app_t app, ctrl_t ctrl,
 
 /* Handle the GENKEY command. */
 static gpg_error_t
-do_genkey (app_t app, ctrl_t ctrl,  const char *keynostr, unsigned int flags,
-           time_t createtime,
+do_genkey (app_t app, ctrl_t ctrl,  const char *keynostr, const char *keytype,
+           unsigned int flags, time_t createtime,
            gpg_error_t (*pincb)(void*, const char *, char **),
            void *pincb_arg)
 {
@@ -4103,6 +4103,8 @@ do_genkey (app_t app, ctrl_t ctrl,  const char *keynostr, unsigned int flags,
   int exmode = 0;
   int le_value = 256; /* Use legacy value. */
 
+  (void)keytype;  /* Ignored for OpenPGP cards.  */
+
   if (keyno < 0 || keyno > 2)
     return gpg_error (GPG_ERR_INV_ID);
 
@@ -4151,7 +4153,7 @@ do_genkey (app_t app, ctrl_t ctrl,  const char *keynostr, unsigned int flags,
 
   log_info (_("please wait while key is being generated ...\n"));
   start_at = time (NULL);
-  err = iso7816_generate_keypair (app->slot, exmode,
+  err = iso7816_generate_keypair (app->slot, exmode, 0x80, 0,
                                   (keyno == 0? "\xB6" :
                                    keyno == 1? "\xB8" : "\xA4"),
                                   2, le_value, &buffer, &buflen);
diff --git a/scd/app.c b/scd/app.c
index c6c1f84..2e2729e 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -939,8 +939,8 @@ app_writekey (app_t app, ctrl_t ctrl,
 
 /* Perform a SETATTR operation.  */
 gpg_error_t
-app_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags,
-            time_t createtime,
+app_genkey (app_t app, ctrl_t ctrl, const char *keynostr,
+            const char *keytype, unsigned int flags, time_t createtime,
             gpg_error_t (*pincb)(void*, const char *, char **),
             void *pincb_arg)
 {
@@ -955,7 +955,7 @@ app_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags,
   err = lock_app (app, ctrl);
   if (err)
     return err;
-  err = app->fnc.genkey (app, ctrl, keynostr, flags,
+  err = app->fnc.genkey (app, ctrl, keynostr, keytype, flags,
                          createtime, pincb, pincb_arg);
   unlock_app (app);
   if (opt.verbose)
diff --git a/scd/command.c b/scd/command.c
index fb0ba98..8fd6ba5 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -1190,7 +1190,8 @@ cmd_genkey (assuan_context_t ctx, char *line)
   keyno = xtrystrdup (keyno);
   if (!keyno)
     return out_of_core ();
-  rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0,
+  rc = app_genkey (ctrl->app_ctx, ctrl, keyno, NULL,
+                   force? APP_GENKEY_FLAG_FORCE : 0,
                    timestamp, pin_cb, ctx);
   xfree (keyno);
 
diff --git a/scd/iso7816.c b/scd/iso7816.c
index 69009c4..758de5b 100644
--- a/scd/iso7816.c
+++ b/scd/iso7816.c
@@ -709,7 +709,7 @@ iso7816_general_authenticate (int slot, int extended_mode,
    returned.  In that case a value of -1 uses a large default
    (e.g. 4096 bytes), a value larger 256 used that value.  */
 static gpg_error_t
-do_generate_keypair (int slot, int extended_mode, int read_only,
+do_generate_keypair (int slot, int extended_mode, int p1, int p2,
                      const char *data, size_t datalen, int le,
                      unsigned char **result, size_t *resultlen)
 {
@@ -721,7 +721,7 @@ do_generate_keypair (int slot, int extended_mode, int read_only,
   *resultlen = 0;
 
   sw = apdu_send_le (slot, extended_mode,
-                     0x00, CMD_GENERATE_KEYPAIR, read_only? 0x81:0x80, 0,
+                     0x00, CMD_GENERATE_KEYPAIR, p1, p2,
                      datalen, data,
                      le >= 0 && le < 256? 256:le,
                      result, resultlen);
@@ -739,12 +739,12 @@ do_generate_keypair (int slot, int extended_mode, int read_only,
 
 
 gpg_error_t
-iso7816_generate_keypair (int slot, int extended_mode,
+iso7816_generate_keypair (int slot, int extended_mode, int p1, int p2,
                           const char *data, size_t datalen,
                           int le,
                           unsigned char **result, size_t *resultlen)
 {
-  return do_generate_keypair (slot, extended_mode, 0,
+  return do_generate_keypair (slot, extended_mode, p1, p2,
                               data, datalen, le, result, resultlen);
 }
 
@@ -755,7 +755,7 @@ iso7816_read_public_key (int slot, int extended_mode,
                          int le,
                          unsigned char **result, size_t *resultlen)
 {
-  return do_generate_keypair (slot, extended_mode, 1,
+  return do_generate_keypair (slot, extended_mode, 0x81, 0,
                               data, datalen, le, result, resultlen);
 }
 
diff --git a/scd/iso7816.h b/scd/iso7816.h
index 4a366e6..df5d25f 100644
--- a/scd/iso7816.h
+++ b/scd/iso7816.h
@@ -112,9 +112,11 @@ gpg_error_t iso7816_general_authenticate (int slot, int extended_mode,
                                           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,
-                                    unsigned char **result, size_t *resultlen);
+                                      int p1, int p2,
+                                      const char *data, size_t datalen,
+                                      int le,
+                                      unsigned char **result,
+                                      size_t *resultlen);
 gpg_error_t iso7816_read_public_key (int slot, int extended_mode,
                                     const char *data, size_t datalen,
                                     int le,

commit c26af8ac263ea006ed32e110a09271e4bfbf1f37
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Feb 6 12:24:30 2019 +0100

    scd: Fix parameter name of app_change_key.
    
    * scd/app-common.h (APP_GENKEY_FLAG_FORCE): New.
    * scd/app.c (app_change_pin): Rename arg reset_mode to flags and
    change from int to unsigned int.
    --
    
    This is basically a documentation fix.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/scd/app-common.h b/scd/app-common.h
index 98d8464..d8b301c 100644
--- a/scd/app-common.h
+++ b/scd/app-common.h
@@ -25,11 +25,14 @@
 #include <npth.h>
 #include <ksba.h>
 
-
+/* Flags used with app_change_pin.  */
 #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.  */
 
+/* Flags used with app_genkey.  */
+#define APP_GENKEY_FLAG_FORCE    1  /* Force overwriting existing key.  */
+
 /* Bit flags set by the decipher function into R_INFO.  */
 #define APP_DECIPHER_INFO_NOPAD  1  /* Padding has been removed.  */
 
@@ -182,9 +185,9 @@ gpg_error_t app_genkey (app_t app, ctrl_t ctrl,
 gpg_error_t app_get_challenge (app_t app, ctrl_t ctrl, size_t nbytes,
                                unsigned char *buffer);
 gpg_error_t app_change_pin (app_t app, ctrl_t ctrl,
-                    const char *chvnostr, int reset_mode,
-                    gpg_error_t (*pincb)(void*, const char *, char **),
-                    void *pincb_arg);
+                            const char *chvnostr, unsigned int flags,
+                            gpg_error_t (*pincb)(void*, const char *, char **),
+                            void *pincb_arg);
 gpg_error_t app_check_pin (app_t app, ctrl_t ctrl, const char *keyidstr,
                    gpg_error_t (*pincb)(void*, const char *, char **),
                    void *pincb_arg);
diff --git a/scd/app.c b/scd/app.c
index c79a174..c6c1f84 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -988,7 +988,8 @@ app_get_challenge (app_t app, ctrl_t ctrl, size_t nbytes, unsigned char *buffer)
 
 /* Perform a CHANGE REFERENCE DATA or RESET RETRY COUNTER operation.  */
 gpg_error_t
-app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode,
+app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr,
+                unsigned int flags,
                 gpg_error_t (*pincb)(void*, const char *, char **),
                 void *pincb_arg)
 {
@@ -1003,8 +1004,7 @@ app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode,
   err = lock_app (app, ctrl);
   if (err)
     return err;
-  err = app->fnc.change_pin (app, ctrl, chvnostr, reset_mode,
-                             pincb, pincb_arg);
+  err = app->fnc.change_pin (app, ctrl, chvnostr, flags, pincb, pincb_arg);
   unlock_app (app);
   if (opt.verbose)
     log_info ("operation change_pin result: %s\n", gpg_strerror (err));

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

Summary of changes:
 scd/app-common.h  |  19 +--
 scd/app-openpgp.c |   8 +-
 scd/app-piv.c     | 362 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 scd/app.c         |  12 +-
 scd/command.c     |   3 +-
 scd/iso7816.c     |  10 +-
 scd/iso7816.h     |   8 +-
 7 files changed, 389 insertions(+), 33 deletions(-)


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




More information about the Gnupg-commits mailing list