diff --git a/g10/call-agent.c b/g10/call-agent.c index 080df1867..cadc02c6f 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -639,9 +639,9 @@ learn_status_cb (void *opaque, const char *line) return 0; } -/* Call the agent to learn about a smartcard */ +/* Call the scdaemon to learn about a smartcard */ int -agent_learn (struct agent_card_info_s *info) +agent_scd_learn (struct agent_card_info_s *info) { int rc; struct default_inq_parm_s parm; @@ -677,6 +677,29 @@ agent_learn (struct agent_card_info_s *info) } +/* Call the agent to learn about the current smartcard. This is + currently only used to have the agent create the shadow key. */ +gpg_error_t +agent_learn (void) +{ + gpg_error_t err; + struct default_inq_parm_s parm; + + memset (&parm, 0, sizeof parm); + + err = start_agent (NULL, 1); + if (err) + return err; + + parm.ctx = agent_ctx; + err = assuan_transact (agent_ctx, "LEARN", + dummy_data_cb, NULL, default_inq_cb, &parm, + NULL, NULL); + + return err; +} + + int agent_keytocard (const char *hexgrip, int keyno, int force, const char *serialno, const char *timestamp) diff --git a/g10/call-agent.h b/g10/call-agent.h index 5b4cd0931..a99cac990 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -76,7 +76,10 @@ struct agent_card_genkey_s { void agent_release_card_info (struct agent_card_info_s *info); /* Return card info. */ -int agent_learn (struct agent_card_info_s *info); +int agent_scd_learn (struct agent_card_info_s *info); + +/* Let the agent learn about the current card. */ +gpg_error_t agent_learn (void); /* Update INFO with the attribute NAME. */ int agent_scd_getattr (const char *name, struct agent_card_info_s *info); diff --git a/g10/card-util.c b/g10/card-util.c index b5be80ac2..d7a67544d 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -80,7 +80,7 @@ change_pin (int unblock_v2, int allow_admin) struct agent_card_info_s info; int rc; - rc = agent_learn (&info); + rc = agent_scd_learn (&info); if (rc) { log_error (_("OpenPGP card not available: %s\n"), @@ -370,7 +370,7 @@ card_status (estream_t fp, char *serialno, size_t serialnobuflen) if (serialno && serialnobuflen) *serialno = 0; - rc = agent_learn (&info); + rc = agent_scd_learn (&info); if (rc) { if (opt.with_colons) diff --git a/g10/keygen.c b/g10/keygen.c index 80954527c..e25ecc389 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -4510,6 +4510,19 @@ 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 + card key. We need to do that now so that we are able to create + the self-signatures. */ + err = agent_learn (); + if (err) + { + /* Oops: Card removed during generation. */ + log_error (_("OpenPGP card not available: %s\n"), gpg_strerror (err)); + xfree (pkt); + xfree (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;