g10: Fix keytocard.
authorNIIBE Yutaka <gniibe@fsij.org>
Fri, 3 Apr 2015 08:39:59 +0000 (17:39 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Fri, 3 Apr 2015 08:39:59 +0000 (17:39 +0900)
g10/call-agent.h (agent_scd_learn): Add FORCE option.
g10/call-agent.c (agent_scd_learn): Implement FORCE option.
g10/keygen.c (gen_card_key): Follow the change of option.
g10/card-util.c (change_pin, card_status, factory_reset): Likewise.
g10/keyedit.c (keyedit_menu): Update private key storage by
agent_scd_learn.
--

This is not a perfect solution since there is a possibility user
unplug card before quitting 'gpg --keyedit' session.  Usually,
it works well.

GnuPG-bug-id: 1846

g10/call-agent.c
g10/call-agent.h
g10/card-util.c
g10/keyedit.c
g10/keygen.c

index 4bac8a0..2a80f22 100644 (file)
@@ -673,7 +673,7 @@ learn_status_cb (void *opaque, const char *line)
 
 /* Call the scdaemon to learn about a smartcard */
 int
 
 /* Call the scdaemon to learn about a smartcard */
 int
-agent_scd_learn (struct agent_card_info_s *info)
+agent_scd_learn (struct agent_card_info_s *info, int force)
 {
   int rc;
   struct default_inq_parm_s parm;
 {
   int rc;
   struct default_inq_parm_s parm;
@@ -701,7 +701,8 @@ agent_scd_learn (struct agent_card_info_s *info)
     return rc;
 
   parm.ctx = agent_ctx;
     return rc;
 
   parm.ctx = agent_ctx;
-  rc = assuan_transact (agent_ctx, "LEARN --sendinfo",
+  rc = assuan_transact (agent_ctx,
+                        force ? "LEARN --sendinfo --force" : "LEARN --sendinfo",
                         dummy_data_cb, NULL, default_inq_cb, &parm,
                         learn_status_cb, info);
   /* Also try to get the key attributes.  */
                         dummy_data_cb, NULL, default_inq_cb, &parm,
                         learn_status_cb, info);
   /* Also try to get the key attributes.  */
index 9c104e8..df570a4 100644 (file)
@@ -77,7 +77,7 @@ struct agent_card_genkey_s {
 void agent_release_card_info (struct agent_card_info_s *info);
 
 /* Return card info. */
 void agent_release_card_info (struct agent_card_info_s *info);
 
 /* Return card info. */
-int agent_scd_learn (struct agent_card_info_s *info);
+int agent_scd_learn (struct agent_card_info_s *info, int force);
 
 /* Send an APDU to the card.  */
 gpg_error_t agent_scd_apdu (const char *hexapdu, unsigned int *r_sw);
 
 /* Send an APDU to the card.  */
 gpg_error_t agent_scd_apdu (const char *hexapdu, unsigned int *r_sw);
index 4b584bf..a291a07 100644 (file)
@@ -81,7 +81,7 @@ change_pin (int unblock_v2, int allow_admin)
   struct agent_card_info_s info;
   int rc;
 
   struct agent_card_info_s info;
   int rc;
 
-  rc = agent_scd_learn (&info);
+  rc = agent_scd_learn (&info, 0);
   if (rc)
     {
       log_error (_("OpenPGP card not available: %s\n"),
   if (rc)
     {
       log_error (_("OpenPGP card not available: %s\n"),
@@ -374,7 +374,7 @@ card_status (estream_t fp, char *serialno, size_t serialnobuflen)
   if (serialno && serialnobuflen)
     *serialno = 0;
 
   if (serialno && serialnobuflen)
     *serialno = 0;
 
-  rc = agent_scd_learn (&info);
+  rc = agent_scd_learn (&info, 0);
   if (rc)
     {
       if (opt.with_colons)
   if (rc)
     {
       if (opt.with_colons)
@@ -1702,7 +1702,7 @@ factory_reset (void)
       but tries to find out something about the card first.
    */
 
       but tries to find out something about the card first.
    */
 
-  err = agent_scd_learn (&info);
+  err = agent_scd_learn (&info, 0);
   if (gpg_err_code (err) == GPG_ERR_OBJ_TERM_STATE
       && gpg_err_source (err) == GPG_ERR_SOURCE_SCD)
     termstate = 1;
   if (gpg_err_code (err) == GPG_ERR_OBJ_TERM_STATE
       && gpg_err_source (err) == GPG_ERR_SOURCE_SCD)
     termstate = 1;
index 91f5dae..2f9469f 100644 (file)
@@ -1450,6 +1450,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
   char *answer = NULL;
   int redisplay = 1;
   int modified = 0;
   char *answer = NULL;
   int redisplay = 1;
   int modified = 0;
+  int sec_shadowing = 0;
   int run_subkey_warnings = 0;
   int toggle;
   int have_commands = !!commands;
   int run_subkey_warnings = 0;
   int toggle;
   int have_commands = !!commands;
@@ -1836,8 +1837,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
                if (card_store_subkey (node, xxpk ? xxpk->pubkey_usage : 0))
                  {
                    redisplay = 1;
                if (card_store_subkey (node, xxpk ? xxpk->pubkey_usage : 0))
                  {
                    redisplay = 1;
-                   /* Only the secret key has been modified; thus
-                       there is no need to set the modified flag.  */
+                   sec_shadowing = 1;
                  }
              }
          }
                  }
              }
          }
@@ -1923,7 +1923,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
                if (card_store_subkey (node, 0))
                  {
                    redisplay = 1;
                if (card_store_subkey (node, 0))
                  {
                    redisplay = 1;
-                   /* FIXME:sec_modified = 1;*/
+                   sec_shadowing = 1;
                  }
              }
            release_kbnode (node);
                  }
              }
            release_kbnode (node);
@@ -2182,7 +2182,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
        case cmdQUIT:
          if (have_commands)
            goto leave;
        case cmdQUIT:
          if (have_commands)
            goto leave;
-         if (!modified)
+         if (!modified && !sec_shadowing)
            goto leave;
          if (!cpr_get_answer_is_yes ("keyedit.save.okay",
                                      _("Save changes? (y/N) ")))
            goto leave;
          if (!cpr_get_answer_is_yes ("keyedit.save.okay",
                                      _("Save changes? (y/N) ")))
@@ -2204,7 +2204,18 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
                   break;
                 }
            }
                   break;
                 }
            }
-         else
+
+         if (sec_shadowing)
+           {
+             err = agent_scd_learn (NULL, 1);
+             if (err)
+                {
+                  log_error (_("update failed: %s\n"), gpg_strerror (err));
+                  break;
+                }
+           }
+
+         if (!modified && !sec_shadowing)
            tty_printf (_("Key not changed so no update needed.\n"));
 
          if (update_trust)
            tty_printf (_("Key not changed so no update needed.\n"));
 
          if (update_trust)
index 769e193..4b0398a 100644 (file)
@@ -4487,7 +4487,7 @@ gen_card_key (int algo, int keyno, int is_primary, kbnode_t pub_root,
   /* Send the learn 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. */
   /* Send the learn 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);
+  err = agent_scd_learn (NULL, 0);
   if (err)
     {
       /* Oops: Card removed during generation.  */
   if (err)
     {
       /* Oops: Card removed during generation.  */