aboutsummaryrefslogtreecommitdiffstats
path: root/sm/call-agent.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--sm/call-agent.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/sm/call-agent.c b/sm/call-agent.c
index 1f8eecb3b..777c44cec 100644
--- a/sm/call-agent.c
+++ b/sm/call-agent.c
@@ -538,8 +538,150 @@ gpgsm_agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip,
return 0;
}
+
+/* Take the serial number from LINE and return it verbatim in a newly
+ allocated string. We make sure that only hex characters are
+ returned. */
+static char *
+store_serialno (const char *line)
+{
+ const char *s;
+ char *p;
+
+ for (s=line; hexdigitp (s); s++)
+ ;
+ p = xtrymalloc (s + 1 - line);
+ if (p)
+ {
+ memcpy (p, line, s-line);
+ p[s-line] = 0;
+ }
+ return p;
+}
+
+
+/* Callback for the gpgsm_agent_serialno fucntion. */
+static int
+scd_serialno_status_cb (void *opaque, const char *line)
+{
+ char **r_serialno = opaque;
+ const char *keyword = line;
+ int keywordlen;
+
+ for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
+ ;
+ while (spacep (line))
+ line++;
+
+ if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
+ {
+ xfree (*r_serialno);
+ *r_serialno = store_serialno (line);
+ }
+
+ return 0;
+}
+
+
+/* Call the agent to read the serial number of the current card. */
+int
+gpgsm_agent_scd_serialno (ctrl_t ctrl, char **r_serialno)
+{
+ int rc;
+ char *serialno = NULL;
+
+ *r_serialno = NULL;
+ rc = start_agent (ctrl);
+ if (rc)
+ return rc;
+ rc = assuan_transact (agent_ctx, "SCD SERIALNO",
+ NULL, NULL,
+ default_inq_cb, ctrl,
+ scd_serialno_status_cb, &serialno);
+ if (!rc && !serialno)
+ rc = gpg_error (GPG_ERR_INTERNAL);
+ if (rc)
+ {
+ xfree (serialno);
+ return rc;
+ }
+ *r_serialno = serialno;
+ return 0;
+}
+
+
+
+/* Callback for the gpgsm_agent_serialno fucntion. */
+static int
+scd_keypairinfo_status_cb (void *opaque, const char *line)
+{
+ strlist_t *listaddr = opaque;
+ const char *keyword = line;
+ int keywordlen;
+ strlist_t sl;
+ char *p;
+
+ for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
+ ;
+ while (spacep (line))
+ line++;
+
+ if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen))
+ {
+ sl = append_to_strlist (listaddr, line);
+ p = sl->d;
+ /* Make sure that we only have two tokes so that future
+ extensions of the format won't change the format expected by
+ the caller. */
+ while (*p && !spacep (p))
+ p++;
+ if (*p)
+ {
+ while (spacep (p))
+ p++;
+ while (*p && !spacep (p))
+ p++;
+ *p = 0;
+ }
+ }
+
+ return 0;
+}
+
+
+/* Call the agent to read the keypairinfo lines of the current card.
+ The list is returned as a string made up of the keygrip, a space
+ and the keyid. */
+int
+gpgsm_agent_scd_keypairinfo (ctrl_t ctrl, strlist_t *r_list)
+{
+ int rc;
+ strlist_t list = NULL;
+
+ *r_list = NULL;
+ rc = start_agent (ctrl);
+ if (rc)
+ return rc;
+
+ rc = assuan_transact (agent_ctx, "SCD LEARN --force",
+ NULL, NULL,
+ default_inq_cb, ctrl,
+ scd_keypairinfo_status_cb, &list);
+ if (!rc && !list)
+ rc = gpg_error (GPG_ERR_NO_DATA);
+ if (rc)
+ {
+ free_strlist (list);
+ return rc;
+ }
+ *r_list = list;
+ return 0;
+}
+
+
+
static int
istrusted_status_cb (void *opaque, const char *line)
{