[git] GnuPG - branch, master, updated. gnupg-2.1.15-248-g980c037

by NIIBE Yutaka cvs at cvs.gnupg.org
Thu Oct 20 06:43:37 CEST 2016


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  980c037bedb968ddf155dd334c0a70b918a17759 (commit)
       via  82cbab906a3e72a98fdc16096f2f0451465969a2 (commit)
      from  72a99f582dad4cb4c3b05b97c7ebb8d537f10b79 (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 980c037bedb968ddf155dd334c0a70b918a17759
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Thu Oct 20 13:30:47 2016 +0900

    g10: smartcard keygen change.
    
    * g10/call-agent.c (scd_genkey_cb_append_savedbytes): Remove.
    (scd_genkey_cb): Only handle KEY-CREATED-AT and PROGRESS.
    (agent_scd_genkey): Remove INFO argument.  CREATETIME is now in/out
    argument.
    (agent_readkey): Use READKEY --card instead of SCD READKEY.
    * g10/keygen.c (gen_card_key): Use READKEY --card command of the agent
    to retrieve public key information from card and let the agent make
    a file for private key with shadow info.
    --
    
    This change removes gpg's KEY-DATA handling for SCD GENKEY.  Information
    with KEY-DATA is simply not used.  Instead, it is read by READKEY --card
    command of gpg-agent.  This can consolidate public key handling in a
    single method by READKEY.
    
    Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>

diff --git a/g10/call-agent.c b/g10/call-agent.c
index 0fb392c..632cabe 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -103,13 +103,6 @@ struct cache_nonce_parm_s
 };
 
 
-struct scd_genkey_parm_s
-{
-  struct agent_card_genkey_s *cgk;
-  char *savedbytes;     /* Malloced space to save key parameter chunks.  */
-};
-
-
 static gpg_error_t learn_status_cb (void *opaque, const char *line);
 
 
@@ -979,133 +972,50 @@ agent_scd_writekey (int keyno, const char *serialno,
 
 
 

-static gpg_error_t
-scd_genkey_cb_append_savedbytes (struct scd_genkey_parm_s *parm,
-                                 const char *line)
-{
-  gpg_error_t err = 0;
-  char *p;
-
-  if (!parm->savedbytes)
-    {
-      parm->savedbytes = xtrystrdup (line);
-      if (!parm->savedbytes)
-        err = gpg_error_from_syserror ();
-    }
-  else
-    {
-      p = xtrymalloc (strlen (parm->savedbytes) + strlen (line) + 1);
-      if (!p)
-        err = gpg_error_from_syserror ();
-      else
-        {
-          strcpy (stpcpy (p, parm->savedbytes), line);
-          xfree (parm->savedbytes);
-          parm->savedbytes = p;
-        }
-    }
-
-  return err;
-}
-
 /* Status callback for the SCD GENKEY command. */
 static gpg_error_t
 scd_genkey_cb (void *opaque, const char *line)
 {
-  struct scd_genkey_parm_s *parm = opaque;
+  u32 *createtime = opaque;
   const char *keyword = line;
   int keywordlen;
-  gpg_error_t rc = 0;
 
   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
     ;
   while (spacep (line))
     line++;
 
-  if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
-    {
-      parm->cgk->fprvalid = unhexify_fpr (line, parm->cgk->fpr);
-    }
-  else if (keywordlen == 8 && !memcmp (keyword, "KEY-DATA", keywordlen))
-    {
-      gcry_mpi_t a;
-      const char *name = line;
-
-      while (*line && !spacep (line))
-        line++;
-      while (spacep (line))
-        line++;
-
-      if (*name == '-' && spacep (name+1))
-        rc = scd_genkey_cb_append_savedbytes (parm, line);
-      else
-        {
-          if (parm->savedbytes)
-            {
-              rc = scd_genkey_cb_append_savedbytes (parm, line);
-              if (!rc)
-                rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX,
-                                    parm->savedbytes, 0, NULL);
-            }
-          else
-            rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, line, 0, NULL);
-          if (rc)
-            log_error ("error parsing received key data: %s\n",
-                       gpg_strerror (rc));
-          else if (*name == 'n' && spacep (name+1))
-            parm->cgk->n = a;
-          else if (*name == 'e' && spacep (name+1))
-            parm->cgk->e = a;
-          else
-            {
-              log_info ("unknown parameter name in received key data\n");
-              gcry_mpi_release (a);
-              rc = gpg_error (GPG_ERR_INV_PARAMETER);
-            }
-
-          xfree (parm->savedbytes);
-          parm->savedbytes = NULL;
-        }
-    }
-  else if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
+ if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
     {
-      parm->cgk->created_at = (u32)strtoul (line, NULL, 10);
+      *createtime = (u32)strtoul (line, NULL, 10);
     }
   else if (keywordlen == 8 && !memcmp (keyword, "PROGRESS", keywordlen))
     {
       write_status_text (STATUS_PROGRESS, line);
     }
 
-  return rc;
+  return 0;
 }
 
-/* Send a GENKEY command to the SCdaemon.  SERIALNO is not used in
-   this implementation.  If CREATEDATE is not 0, it will be passed to
-   SCDAEMON so that the key is created with this timestamp.  INFO will
-   receive information about the generated key.  */
+/* Send a GENKEY command to the SCdaemon.  If CREATETIME is not 0, it
+  will be passed to SCDAEMON so that the key is created with this
+  timestamp.  On success, creation time  is stored back to CREATETIME.  */
 int
-agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
-                  const char *serialno, u32 createtime)
+agent_scd_genkey (int keyno, int force, u32 *createtime)
 {
   int rc;
   char line[ASSUAN_LINELENGTH];
   gnupg_isotime_t tbuf;
-  struct scd_genkey_parm_s parms;
   struct default_inq_parm_s dfltparm;
 
   memset (&dfltparm, 0, sizeof dfltparm);
 
-  (void)serialno;
-
-  memset (&parms, 0, sizeof parms);
-  parms.cgk = info;
-
   rc = start_agent (NULL, 1);
   if (rc)
     return rc;
 
-  if (createtime)
-    epoch2isotime (tbuf, createtime);
+  if (*createtime)
+    epoch2isotime (tbuf, *createtime);
   else
     *tbuf = 0;
 
@@ -1116,12 +1026,9 @@ agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
   line[DIM(line)-1] = 0;
 
   dfltparm.ctx = agent_ctx;
-  memset (info, 0, sizeof *info);
   rc = assuan_transact (agent_ctx, line,
                         NULL, NULL, default_inq_cb, &dfltparm,
-                        scd_genkey_cb, &parms);
-
-  xfree (parms.savedbytes);
+                        scd_genkey_cb, createtime);
 
   status_sc_op_failure (rc);
   return rc;
@@ -1854,7 +1761,8 @@ agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip,
   if (err)
     return err;
 
-  snprintf (line, DIM(line)-1, "%sREADKEY %s", fromcard? "SCD ":"", hexkeygrip);
+  snprintf (line, DIM(line)-1, "READKEY %s%s", fromcard? "--card ":"",
+            hexkeygrip);
 
   init_membuf (&data, 1024);
   err = assuan_transact (agent_ctx, line,
diff --git a/g10/call-agent.h b/g10/call-agent.h
index d85a6fd..032c345 100644
--- a/g10/call-agent.h
+++ b/g10/call-agent.h
@@ -68,13 +68,6 @@ struct agent_card_info_s
   unsigned int status_indicator;
 };
 
-struct agent_card_genkey_s {
-  char fprvalid;
-  char fpr[20];
-  u32  created_at;
-  gcry_mpi_t n;
-  gcry_mpi_t e;
-};
 
 
 /* Release the card info structure. */
@@ -107,8 +100,7 @@ int agent_scd_writekey (int keyno, const char *serialno,
                         const unsigned char *keydata, size_t keydatalen);
 
 /* Send a GENKEY command to the SCdaemon. */
-int agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
-                      const char *serialno, u32 createtime);
+int agent_scd_genkey (int keyno, int force, u32 *createtime);
 
 /* Send a READKEY command to the SCdaemon. */
 int agent_scd_readcert (const char *certidstr,
diff --git a/g10/keygen.c b/g10/keygen.c
index 9cf314d..90f8544 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -4870,9 +4870,14 @@ gen_card_key (int algo, int keyno, int is_primary, kbnode_t pub_root,
 {
 #ifdef ENABLE_CARD_SUPPORT
   gpg_error_t err;
-  struct agent_card_genkey_s info;
   PACKET *pkt;
   PKT_public_key *pk;
+  char keyid[10];
+  unsigned char *public;
+  gcry_sexp_t s_key;
+
+  snprintf (keyid, DIM(keyid)-1, "OPENPGP.%d", keyno);
+  keyid[DIM(keyid)-1] = 0;
 
   if (algo != PUBKEY_ALGO_RSA)
     return gpg_error (GPG_ERR_PUBKEY_ALGO);
@@ -4888,7 +4893,7 @@ gen_card_key (int algo, int keyno, int is_primary, kbnode_t pub_root,
     }
 
   /* Note: SCD knows the serialnumber, thus there is no point in passing it.  */
-  err = agent_scd_genkey (&info, keyno, 1, NULL, *timestamp);
+  err = agent_scd_genkey (keyno, 1, timestamp);
   /*  The code below is not used because we force creation of
    *  the a card key (3rd arg).
    * if (gpg_err_code (rc) == GPG_ERR_EEXIST)
@@ -4898,16 +4903,9 @@ gen_card_key (int algo, int keyno, int is_primary, kbnode_t pub_root,
    *     tty_printf ("\n");
    *     if ( cpr_get_answer_is_yes( "keygen.card.replace_key",
    *                                 _("Replace existing key? ")))
-   *       rc = agent_scd_genkey (&info, keyno, 1);
+   *       rc = agent_scd_genkey (keyno, 1, timestamp);
    *   }
   */
-  if (!err && (!info.n || !info.e))
-    {
-      log_error ("communication error with SCD\n");
-      gcry_mpi_release (info.n);
-      gcry_mpi_release (info.e);
-      err =  gpg_error (GPG_ERR_GENERAL);
-    }
   if (err)
     {
       log_error ("key generation failed: %s\n", gpg_strerror (err));
@@ -4916,30 +4914,40 @@ gen_card_key (int algo, int keyno, int is_primary, kbnode_t pub_root,
       return err;
     }
 
-  /* Send the learn command so that the agent creates a shadow key for
+  /* Send the READKEY command so that the agent creates a shadow key for
      card key.  We need to do that now so that we are able to create
      the self-signatures. */
-  err = agent_scd_learn (NULL, 0);
+  err = agent_readkey (NULL, 1, keyid, &public);
+  if (err)
+    return err;
+  err = gcry_sexp_sscan (&s_key, NULL, public,
+                         gcry_sexp_canon_len (public, 0, NULL, NULL));
+  xfree (public);
+  if (err)
+    return err;
+
+  if (algo == PUBKEY_ALGO_RSA)
+    err = key_from_sexp (pk->pkey, s_key, "public-key", "ne");
+  else if (algo == PUBKEY_ALGO_ECDSA
+	   || algo == PUBKEY_ALGO_EDDSA
+	   || algo == PUBKEY_ALGO_ECDH )
+    err = ecckey_from_sexp (pk->pkey, s_key, algo);
+  else
+    err = gpg_error (GPG_ERR_PUBKEY_ALGO);
+  gcry_sexp_release (s_key);
+
   if (err)
     {
-      /* Oops: Card removed during generation.  */
-      log_error (_("OpenPGP card not available: %s\n"), gpg_strerror (err));
-      xfree (pkt);
-      xfree (pk);
+      log_error ("key_from_sexp failed: %s\n", gpg_strerror (err) );
+      free_public_key (pk);
       return err;
     }
 
-  if (*timestamp != info.created_at)
-    log_info ("NOTE: the key does not use the suggested creation date\n");
-  *timestamp = info.created_at;
-
-  pk->timestamp = info.created_at;
+  pk->timestamp = *timestamp;
   pk->version = 4;
   if (expireval)
     pk->expiredate = pk->timestamp + expireval;
   pk->pubkey_algo = algo;
-  pk->pkey[0] = info.n;
-  pk->pkey[1] = info.e;
 
   pkt->pkttype = is_primary ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY;
   pkt->pkt.public_key = pk;

commit 82cbab906a3e72a98fdc16096f2f0451465969a2
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Thu Oct 20 12:05:15 2016 +0900

    agent: Add --card option for READKEY.
    
    * agent/findkey.c (agent_write_shadow_key): New.
    * agent/command-ssh.c (card_key_available): Use agent_write_shadow_key.
    * agent/learncard.c (agent_handle_learn): Likewise.
    * agent/command.c (cmd_readkey): Add --card option.
    --
    
    Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>

diff --git a/agent/agent.h b/agent/agent.h
index fe5ffba..a3ec457 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -490,6 +490,9 @@ gpg_error_t s2k_hash_passphrase (const char *passphrase, int hashalgo,
                                  const unsigned char *s2ksalt,
                                  unsigned int s2kcount,
                                  unsigned char *key, size_t keylen);
+gpg_error_t agent_write_shadow_key (const unsigned char *grip,
+                                    const char *serialno, const char *keyid,
+                                    const unsigned char *pkbuf, int force);
 
 
 /*-- trustlist.c --*/
diff --git a/agent/command-ssh.c b/agent/command-ssh.c
index 083b8d8..7bcda50 100644
--- a/agent/command-ssh.c
+++ b/agent/command-ssh.c
@@ -2474,39 +2474,9 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
   if ( agent_key_available (grip) )
     {
       /* (Shadow)-key is not available in our key storage.  */
-      unsigned char *shadow_info;
-      unsigned char *tmp;
-
-      shadow_info = make_shadow_info (serialno, authkeyid);
-      if (!shadow_info)
-        {
-          err = gpg_error_from_syserror ();
-          xfree (pkbuf);
-          gcry_sexp_release (s_pk);
-          xfree (serialno);
-          xfree (authkeyid);
-          return err;
-        }
-      err = agent_shadow_key (pkbuf, shadow_info, &tmp);
-      xfree (shadow_info);
-      if (err)
-        {
-          log_error (_("shadowing the key failed: %s\n"), gpg_strerror (err));
-          xfree (pkbuf);
-          gcry_sexp_release (s_pk);
-          xfree (serialno);
-          xfree (authkeyid);
-          return err;
-        }
-      xfree (pkbuf);
-      pkbuf = tmp;
-      pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL);
-      assert (pkbuflen);
-
-      err = agent_write_private_key (grip, pkbuf, pkbuflen, 0);
+      err = agent_write_shadow_key (grip, serialno, authkeyid, pkbuf, 0);
       if (err)
         {
-          log_error (_("error writing key: %s\n"), gpg_strerror (err));
           xfree (pkbuf);
           gcry_sexp_release (s_pk);
           xfree (serialno);
diff --git a/agent/command.c b/agent/command.c
index 1ecdf20..a291d5b 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -988,8 +988,10 @@ cmd_genkey (assuan_context_t ctx, char *line)
 

 static const char hlp_readkey[] =
   "READKEY <hexstring_with_keygrip>\n"
+  "        --card <keyid>\n"
   "\n"
-  "Return the public key for the given keygrip.";
+  "Return the public key for the given keygrip or keyid.\n"
+  "With --card, private key file with card information will be created.";
 static gpg_error_t
 cmd_readkey (assuan_context_t ctx, char *line)
 {
@@ -997,10 +999,57 @@ cmd_readkey (assuan_context_t ctx, char *line)
   int rc;
   unsigned char grip[20];
   gcry_sexp_t s_pkey = NULL;
+  unsigned char *pkbuf = NULL;
+  size_t pkbuflen;
 
   if (ctrl->restricted)
     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
 
+  if (has_option_name (line, "--card"))
+    {
+      const char *keyid;
+      char *serialno = NULL;
+
+      keyid = skip_options (line);
+
+      rc = agent_card_getattr (ctrl, "SERIALNO", &serialno);
+      if (rc)
+        {
+          log_error (_("error getting serial number of card: %s\n"),
+                     gpg_strerror (rc));
+          goto leave;
+        }
+
+      pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL);
+      rc = agent_card_readkey (ctrl, keyid, &pkbuf);
+      if (rc)
+        goto leave;
+      rc = gcry_sexp_sscan (&s_pkey, NULL, (char*)pkbuf, pkbuflen);
+      if (rc)
+        goto leave;
+
+      if (!gcry_pk_get_keygrip (s_pkey, grip))
+        {
+          rc = gcry_pk_testkey (s_pkey);
+          if (rc == 0)
+            rc = gpg_error (GPG_ERR_INTERNAL);
+
+          goto leave;
+        }
+
+      rc = agent_write_shadow_key (grip, serialno, keyid, pkbuf, 0);
+      if (rc)
+        goto leave;
+
+      rc = assuan_send_data (ctx, pkbuf, pkbuflen);
+
+ leave:
+      xfree (serialno);
+      xfree (pkbuf);
+      gcry_sexp_release (s_pkey);
+      return leave_cmd (ctx, rc);
+    }
+
   rc = parse_keygrip (ctx, line, grip);
   if (rc)
     return rc; /* Return immediately as this is already an Assuan error code.*/
@@ -1008,20 +1057,16 @@ cmd_readkey (assuan_context_t ctx, char *line)
   rc = agent_public_key_from_file (ctrl, grip, &s_pkey);
   if (!rc)
     {
-      size_t len;
-      unsigned char *buf;
-
-      len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
-      assert (len);
-      buf = xtrymalloc (len);
-      if (!buf)
+      pkbuflen = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
+      assert (pkbuflen);
+      pkbuf = xtrymalloc (pkbuflen);
+      if (!pkbuf)
         rc = gpg_error_from_syserror ();
       else
         {
-          len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, buf, len);
-          assert (len);
-          rc = assuan_send_data (ctx, buf, len);
-          xfree (buf);
+          gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, pkbuf, pkbuflen);
+          rc = assuan_send_data (ctx, pkbuf, pkbuflen);
+          xfree (pkbuf);
         }
       gcry_sexp_release (s_pkey);
     }
diff --git a/agent/findkey.c b/agent/findkey.c
index c5ab0e9..23e94f0 100644
--- a/agent/findkey.c
+++ b/agent/findkey.c
@@ -1492,3 +1492,39 @@ agent_delete_key (ctrl_t ctrl, const char *desc_text,
   gcry_sexp_release (s_skey);
   return err;
 }
+
+
+/* Write an S-expression formatted shadow key to our key storage.
+   Shadow key is created by an S-expression public key in PKBUF and
+   card's SERIALNO and the IDSTRING.  With FORCE passed as true an
+   existing key with the given GRIP will get overwritten.  */
+gpg_error_t
+agent_write_shadow_key (const unsigned char *grip,
+                        const char *serialno, const char *keyid,
+                        const unsigned char *pkbuf, int force)
+{
+  gpg_error_t err;
+  unsigned char *shadow_info;
+  unsigned char *shdkey;
+  size_t len;
+
+  shadow_info = make_shadow_info (serialno, keyid);
+  if (!shadow_info)
+    return gpg_error_from_syserror ();
+
+  err = agent_shadow_key (pkbuf, shadow_info, &shdkey);
+  xfree (shadow_info);
+  if (err)
+    {
+      log_error ("shadowing the key failed: %s\n", gpg_strerror (err));
+      return err;
+    }
+
+  len = gcry_sexp_canon_len (shdkey, 0, NULL, NULL);
+  err = agent_write_private_key (grip, shdkey, len, force);
+  xfree (shdkey);
+  if (err)
+    log_error ("error writing key: %s\n", gpg_strerror (err));
+
+  return err;
+}
diff --git a/agent/learncard.c b/agent/learncard.c
index e9304fb..103a821 100644
--- a/agent/learncard.c
+++ b/agent/learncard.c
@@ -381,8 +381,7 @@ agent_handle_learn (ctrl_t ctrl, int send, void *assuan_context, int force)
 
   for (item = parm.info; item; item = item->next)
     {
-      unsigned char *pubkey, *shdkey;
-      size_t n;
+      unsigned char *pubkey;
 
       if (opt.verbose)
         log_info ("          id: %s    (grip=%s)\n", item->id, item->hexgrip);
@@ -410,33 +409,10 @@ agent_handle_learn (ctrl_t ctrl, int send, void *assuan_context, int force)
           goto leave;
         }
 
-      {
-        unsigned char *shadow_info = make_shadow_info (serialno, item->id);
-        if (!shadow_info)
-          {
-            rc = gpg_error (GPG_ERR_ENOMEM);
-            xfree (pubkey);
-            goto leave;
-          }
-        rc = agent_shadow_key (pubkey, shadow_info, &shdkey);
-        xfree (shadow_info);
-      }
+      rc = agent_write_shadow_key (grip, serialno, item->id, pubkey, force);
       xfree (pubkey);
       if (rc)
-        {
-          log_error ("shadowing the key failed: %s\n", gpg_strerror (rc));
-          goto leave;
-        }
-      n = gcry_sexp_canon_len (shdkey, 0, NULL, NULL);
-      assert (n);
-
-      rc = agent_write_private_key (grip, shdkey, n, force);
-      xfree (shdkey);
-      if (rc)
-        {
-          log_error ("error writing key: %s\n", gpg_strerror (rc));
-          goto leave;
-        }
+        goto leave;
 
       if (opt.verbose)
         log_info ("          id: %s - shadow key created\n", item->id);

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

Summary of changes:
 agent/agent.h       |   3 ++
 agent/command-ssh.c |  32 +-------------
 agent/command.c     |  69 ++++++++++++++++++++++++------
 agent/findkey.c     |  36 ++++++++++++++++
 agent/learncard.c   |  30 ++-----------
 g10/call-agent.c    | 118 ++++++----------------------------------------------
 g10/call-agent.h    |  10 +----
 g10/keygen.c        |  54 ++++++++++++++----------
 8 files changed, 145 insertions(+), 207 deletions(-)


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




More information about the Gnupg-commits mailing list