summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--g10/call-agent.c24
-rw-r--r--g10/call-agent.h3
-rw-r--r--g10/card-util.c1
4 files changed, 30 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index bbf2ad253..7f6b5689f 100644
--- a/NEWS
+++ b/NEWS
@@ -31,6 +31,8 @@ Noteworthy changes in version 2.4.1 (unreleased)
* gpg: Make list-options "show-sig-subpackets" work again.
Fixes regression in 2.4.0. [rG5a223303d7]
+ * gpg: Fix the keytocard command for Yubikeys. [T6378]
+
Release-info: https://dev.gnupg.org/T6454
diff --git a/g10/call-agent.c b/g10/call-agent.c
index 66812e998..131f56ae7 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -1700,6 +1700,30 @@ agent_scd_cardlist (strlist_t *result)
}
+/* Make the app APPNAME the one on the card. This is sometimes
+ * required to make sure no other process has switched a card to
+ * another application. The only useful APPNAME is "openpgp". */
+gpg_error_t
+agent_scd_switchapp (const char *appname)
+{
+ int err;
+ char line[ASSUAN_LINELENGTH];
+
+ if (appname && !*appname)
+ appname = NULL;
+
+ err = start_agent (NULL, (1 | FLAG_FOR_CARD_SUPPRESS_ERRORS));
+ if (err)
+ return err;
+
+ snprintf (line, DIM(line), "SCD SWITCHAPP --%s%s",
+ appname? " ":"", appname? appname:"");
+ return assuan_transact (agent_ctx, line,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL);
+}
+
+
struct card_keyinfo_parm_s {
int error;
diff --git a/g10/call-agent.h b/g10/call-agent.h
index a3f234ade..80595cacc 100644
--- a/g10/call-agent.h
+++ b/g10/call-agent.h
@@ -108,6 +108,9 @@ gpg_error_t agent_scd_keypairinfo (ctrl_t ctrl, const char *keyref,
/* Return list of cards. */
int agent_scd_cardlist (strlist_t *result);
+/* Switch/assure a certain application. */
+gpg_error_t agent_scd_switchapp (const char *appname);
+
/* Free a keypair info list. */
void free_keypair_info (keypair_info_t l);
diff --git a/g10/card-util.c b/g10/card-util.c
index 6451b31e7..d8f1b960a 100644
--- a/g10/card-util.c
+++ b/g10/card-util.c
@@ -1289,6 +1289,7 @@ get_info_for_key_operation (struct agent_card_info_s *info)
int rc;
memset (info, 0, sizeof *info);
+ agent_scd_switchapp ("openpgp");
rc = agent_scd_getattr ("SERIALNO", info);
if (rc || !info->serialno || strncmp (info->serialno, "D27600012401", 12)
|| strlen (info->serialno) != 32 )