1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-15 00:29:49 +02:00

g10: Fix keytocard.

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
This commit is contained in:
NIIBE Yutaka 2015-04-03 17:39:59 +09:00
parent 4ffadb74b3
commit f82c4a6d0d
5 changed files with 24 additions and 12 deletions

View File

@ -673,7 +673,7 @@ learn_status_cb (void *opaque, const char *line)
/* Call the scdaemon to learn about a smartcard */ /* Call the scdaemon to learn about a smartcard */
int int
agent_scd_learn (struct agent_card_info_s *info) agent_scd_learn (struct agent_card_info_s *info, int force)
{ {
int rc; int rc;
struct default_inq_parm_s parm; struct default_inq_parm_s parm;
@ -701,7 +701,8 @@ agent_scd_learn (struct agent_card_info_s *info)
return rc; return rc;
parm.ctx = agent_ctx; 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, dummy_data_cb, NULL, default_inq_cb, &parm,
learn_status_cb, info); learn_status_cb, info);
/* Also try to get the key attributes. */ /* Also try to get the key attributes. */

View File

@ -77,7 +77,7 @@ struct agent_card_genkey_s {
void agent_release_card_info (struct agent_card_info_s *info); void agent_release_card_info (struct agent_card_info_s *info);
/* Return card 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. */ /* Send an APDU to the card. */
gpg_error_t agent_scd_apdu (const char *hexapdu, unsigned int *r_sw); gpg_error_t agent_scd_apdu (const char *hexapdu, unsigned int *r_sw);

View File

@ -81,7 +81,7 @@ change_pin (int unblock_v2, int allow_admin)
struct agent_card_info_s info; struct agent_card_info_s info;
int rc; int rc;
rc = agent_scd_learn (&info); rc = agent_scd_learn (&info, 0);
if (rc) if (rc)
{ {
log_error (_("OpenPGP card not available: %s\n"), 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) if (serialno && serialnobuflen)
*serialno = 0; *serialno = 0;
rc = agent_scd_learn (&info); rc = agent_scd_learn (&info, 0);
if (rc) if (rc)
{ {
if (opt.with_colons) 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 if (gpg_err_code (err) == GPG_ERR_OBJ_TERM_STATE
&& gpg_err_source (err) == GPG_ERR_SOURCE_SCD) && gpg_err_source (err) == GPG_ERR_SOURCE_SCD)
termstate = 1; termstate = 1;

View File

@ -1450,6 +1450,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
char *answer = NULL; char *answer = NULL;
int redisplay = 1; int redisplay = 1;
int modified = 0; int modified = 0;
int sec_shadowing = 0;
int run_subkey_warnings = 0; int run_subkey_warnings = 0;
int toggle; int toggle;
int have_commands = !!commands; 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)) if (card_store_subkey (node, xxpk ? xxpk->pubkey_usage : 0))
{ {
redisplay = 1; redisplay = 1;
/* Only the secret key has been modified; thus sec_shadowing = 1;
there is no need to set the modified flag. */
} }
} }
} }
@ -1923,7 +1923,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
if (card_store_subkey (node, 0)) if (card_store_subkey (node, 0))
{ {
redisplay = 1; 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: case cmdQUIT:
if (have_commands) if (have_commands)
goto leave; goto leave;
if (!modified) if (!modified && !sec_shadowing)
goto leave; goto leave;
if (!cpr_get_answer_is_yes ("keyedit.save.okay", if (!cpr_get_answer_is_yes ("keyedit.save.okay",
_("Save changes? (y/N) "))) _("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")); tty_printf (_("Key not changed so no update needed.\n"));
if (update_trust) if (update_trust)

View 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 /* 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 card key. We need to do that now so that we are able to create
the self-signatures. */ the self-signatures. */
err = agent_scd_learn (NULL); err = agent_scd_learn (NULL, 0);
if (err) if (err)
{ {
/* Oops: Card removed during generation. */ /* Oops: Card removed during generation. */