aboutsummaryrefslogtreecommitdiffstats
path: root/agent/call-scd.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/call-scd.c')
-rw-r--r--agent/call-scd.c72
1 files changed, 70 insertions, 2 deletions
diff --git a/agent/call-scd.c b/agent/call-scd.c
index 790587352..af4d59fbd 100644
--- a/agent/call-scd.c
+++ b/agent/call-scd.c
@@ -102,7 +102,7 @@ start_scd (void)
static AssuanError
learn_status_cb (void *opaque, const char *line)
{
- struct learn_parm_s *parm = opaque;
+ /* struct learn_parm_s *parm = opaque;*/
const char *keyword = line;
int keywordlen;
@@ -127,7 +127,7 @@ learn_status_cb (void *opaque, const char *line)
/* Perform the learn command and return a list of all private keys
stored on the card. */
int
-agent_learn_card (void)
+agent_card_learn (void)
{
int rc;
struct learn_parm_s parm;
@@ -151,3 +151,71 @@ agent_learn_card (void)
return 0;
}
+
+
+static AssuanError
+get_serialno_cb (void *opaque, const char *line)
+{
+ char **serialno = opaque;
+ const char *keyword = line;
+ const char *s;
+ int keywordlen, n;
+
+ for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
+ ;
+ while (spacep (line))
+ line++;
+
+ if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
+ {
+ if (*serialno)
+ return ASSUAN_Unexpected_Status;
+ for (n=0,s=line; hexdigitp (s); s++, n++)
+ ;
+ if (!n || (n&1)|| !(spacep (s) || !*s) )
+ return ASSUAN_Invalid_Status;
+ *serialno = xtrymalloc (n+1);
+ if (!*serialno)
+ return ASSUAN_Out_Of_Core;
+ memcpy (*serialno, line, n);
+ (*serialno)[n] = 0;
+ }
+
+ return 0;
+}
+
+/* Return the serial number of the card or an appropriate error. The
+ serial number is returned as a hext string. */
+int
+agent_card_serialno (char **r_serialno)
+{
+ int rc;
+ char *serialno = NULL;
+
+ rc = start_scd ();
+ if (rc)
+ return rc;
+
+ /* Hmm, do we really need this reset - scddaemon should do this or
+ we can do this if we for some reason figure out that the
+ operation might have failed due to a missing RESET. Hmmm, I feel
+ this is really SCdaemon's duty */
+ rc = assuan_transact (scd_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL);
+ if (rc)
+ return map_assuan_err (rc);
+
+ rc = assuan_transact (scd_ctx, "SERIALNO",
+ NULL, NULL, NULL, NULL,
+ get_serialno_cb, &serialno);
+ if (rc)
+ {
+ xfree (serialno);
+ return map_assuan_err (rc);
+ }
+ *r_serialno = serialno;
+ return 0;
+}
+
+
+
+