aboutsummaryrefslogtreecommitdiffstats
path: root/tools/card-call-scd.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2020-01-16 20:28:45 +0000
committerWerner Koch <[email protected]>2020-01-16 20:28:45 +0000
commitbd85f9232ad639d4acba443272147c4fc01b1b65 (patch)
tree834ec0308c89077102341e4ec492de6f8cd5841a /tools/card-call-scd.c
parentscd: New commands SWITCHCARD and SWITCHAPP. (diff)
downloadgnupg-bd85f9232ad639d4acba443272147c4fc01b1b65.tar.gz
gnupg-bd85f9232ad639d4acba443272147c4fc01b1b65.zip
card: Allow switching of cards and applications.
* tools/card-call-scd.c (struct card_cardlist_parm_s): Add field with_apps. (card_cardlist_cb): Handle the new with_apps flag. (scd_switchcard): New. (scd_switchapp): New. (scd_applist): New. (scd_serialno): Pass --all also in --demand mode. * tools/gpg-card.c (cmd_list): Simplify switching of cards. Add switching of alls. Print a list of apps per card. -- Note that the output format of "list --card" slightly changes: The current card is indicated with an asterisk. That should not harm any robust parsers which might already be in use. It is anyway a development version. Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to 'tools/card-call-scd.c')
-rw-r--r--tools/card-call-scd.c95
1 files changed, 91 insertions, 4 deletions
diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c
index e4fa6abd3..80058efa9 100644
--- a/tools/card-call-scd.c
+++ b/tools/card-call-scd.c
@@ -1,5 +1,5 @@
/* card-call-scd.c - IPC calls to scdaemon.
- * Copyright (C) 2019 g10 Code GmbH
+ * Copyright (C) 2019, 2020 g10 Code GmbH
* Copyright (C) 2001-2003, 2006-2011, 2013 Free Software Foundation, Inc.
* Copyright (C) 2013-2015 Werner Koch
*
@@ -88,6 +88,7 @@ struct genkey_parm_s
struct card_cardlist_parm_s
{
gpg_error_t error;
+ int with_apps;
strlist_t list;
};
@@ -558,6 +559,45 @@ get_serialno_cb (void *opaque, const char *line)
}
+/* Make the card with SERIALNO the current one. */
+gpg_error_t
+scd_switchcard (const char *serialno)
+{
+ int err;
+ char line[ASSUAN_LINELENGTH];
+
+ err = start_agent (START_AGENT_SUPPRESS_ERRORS);
+ if (err)
+ return err;
+
+ snprintf (line, DIM(line), "SCD SWITCHCARD -- %s", serialno);
+ return assuan_transact (agent_ctx, line,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL);
+}
+
+
+/* Make the app APPNAME the one on the card. */
+gpg_error_t
+scd_switchapp (const char *appname)
+{
+ int err;
+ char line[ASSUAN_LINELENGTH];
+
+ if (appname && !*appname)
+ appname = NULL;
+
+ err = start_agent (START_AGENT_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);
+}
+
/* For historical reasons OpenPGP cards simply use the numbers 1 to 3
* for the <keyref>. Other cards and future versions of
@@ -1286,7 +1326,7 @@ scd_serialno (char **r_serialno, const char *demand)
if (!demand)
strcpy (line, "SCD SERIALNO --all");
else
- snprintf (line, DIM(line), "SCD SERIALNO --demand=%s", demand);
+ snprintf (line, DIM(line), "SCD SERIALNO --demand=%s --all", demand);
err = assuan_transact (agent_ctx, line,
NULL, NULL, NULL, NULL,
@@ -1407,10 +1447,24 @@ card_cardlist_cb (void *opaque, const char *line)
for (n=0,s=line; hexdigitp (s); s++, n++)
;
- if (!n || (n&1) || *s)
+ if (!n || (n&1))
parm->error = gpg_error (GPG_ERR_ASS_PARAMETER);
+ if (parm->with_apps)
+ {
+ /* Format of the stored string is the S/N, a space, and a
+ * space separated list of appnames. */
+ if (*s != ' ' || spacep (s+1) || !s[1])
+ parm->error = gpg_error (GPG_ERR_ASS_PARAMETER);
+ else /* We assume the rest of the line is well formatted. */
+ add_to_strlist (&parm->list, line);
+ }
else
- add_to_strlist (&parm->list, line);
+ {
+ if (*s)
+ parm->error = gpg_error (GPG_ERR_ASS_PARAMETER);
+ else
+ add_to_strlist (&parm->list, line);
+ }
}
return 0;
@@ -1446,6 +1500,39 @@ scd_cardlist (strlist_t *result)
}
+/* Return the serial numbers and appnames of the current card or, with
+ * ALL given has true, of all cards currently inserted. */
+gpg_error_t
+scd_applist (strlist_t *result, int all)
+{
+ gpg_error_t err;
+ struct card_cardlist_parm_s parm;
+
+ memset (&parm, 0, sizeof parm);
+ *result = NULL;
+
+ err = start_agent (START_AGENT_SUPPRESS_ERRORS);
+ if (err)
+ return err;
+
+ parm.with_apps = 1;
+ err = assuan_transact (agent_ctx,
+ all ? "SCD GETINFO all_active_apps"
+ /**/: "SCD GETINFO active_apps",
+ NULL, NULL, NULL, NULL,
+ card_cardlist_cb, &parm);
+ if (!err && parm.error)
+ err = parm.error;
+
+ if (!err)
+ *result = parm.list;
+ else
+ free_strlist (parm.list);
+
+ return err;
+}
+
+
/* Change the PIN of an OpenPGP card or reset the retry counter.
* CHVNO 1: Change the PIN