From f82c4a6d0d76e716b6a7b22ca964fa2da1f962a0 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 3 Apr 2015 17:39:59 +0900 Subject: [PATCH] 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 --- g10/call-agent.c | 5 +++-- g10/call-agent.h | 2 +- g10/card-util.c | 6 +++--- g10/keyedit.c | 21 ++++++++++++++++----- g10/keygen.c | 2 +- 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/g10/call-agent.c b/g10/call-agent.c index 4bac8a0ef..2a80f22b8 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -673,7 +673,7 @@ learn_status_cb (void *opaque, const char *line) /* 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; @@ -701,7 +701,8 @@ agent_scd_learn (struct agent_card_info_s *info) 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. */ diff --git a/g10/call-agent.h b/g10/call-agent.h index 9c104e88e..df570a44b 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -77,7 +77,7 @@ struct agent_card_genkey_s { 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); diff --git a/g10/card-util.c b/g10/card-util.c index 4b584bfed..a291a075b 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -81,7 +81,7 @@ change_pin (int unblock_v2, int allow_admin) 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"), @@ -374,7 +374,7 @@ card_status (estream_t fp, char *serialno, size_t serialnobuflen) if (serialno && serialnobuflen) *serialno = 0; - rc = agent_scd_learn (&info); + rc = agent_scd_learn (&info, 0); if (rc) { if (opt.with_colons) @@ -1702,7 +1702,7 @@ factory_reset (void) 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; diff --git a/g10/keyedit.c b/g10/keyedit.c index 91f5dae56..2f9469f17 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -1450,6 +1450,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr, char *answer = NULL; int redisplay = 1; int modified = 0; + int sec_shadowing = 0; 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; - /* 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; - /* FIXME:sec_modified = 1;*/ + sec_shadowing = 1; } } 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; - if (!modified) + if (!modified && !sec_shadowing) 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; } } - 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) diff --git a/g10/keygen.c b/g10/keygen.c index 769e193f2..4b0398a11 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -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. */ - err = agent_scd_learn (NULL); + err = agent_scd_learn (NULL, 0); if (err) { /* Oops: Card removed during generation. */