aboutsummaryrefslogtreecommitdiffstats
path: root/agent/call-scd.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--agent/call-scd.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/agent/call-scd.c b/agent/call-scd.c
index 6cf53fdfd..dd8853f22 100644
--- a/agent/call-scd.c
+++ b/agent/call-scd.c
@@ -403,3 +403,56 @@ agent_card_pksign (const char *keyid,
return 0;
}
+/* Decipher INDATA using the current card. Note that the returned value is */
+int
+agent_card_pkdecrypt (const char *keyid,
+ int (*getpin_cb)(void *, const char *, char*, size_t),
+ void *getpin_cb_arg,
+ const unsigned char *indata, size_t indatalen,
+ char **r_buf, size_t *r_buflen)
+{
+ int rc, i;
+ char *p, line[ASSUAN_LINELENGTH];
+ struct membuf data;
+ struct inq_needpin_s inqparm;
+ size_t len;
+
+ *r_buf = NULL;
+ rc = start_scd ();
+ if (rc)
+ return rc;
+
+ /* FIXME: use secure memory where appropriate */
+ if (indatalen*2 + 50 > DIM(line))
+ return seterr (General_Error);
+
+ sprintf (line, "SETDATA ");
+ p = line + strlen (line);
+ for (i=0; i < indatalen ; i++, p += 2 )
+ sprintf (p, "%02X", indata[i]);
+ rc = assuan_transact (scd_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
+ if (rc)
+ return map_assuan_err (rc);
+
+ init_membuf (&data, 1024);
+ inqparm.ctx = scd_ctx;
+ inqparm.getpin_cb = getpin_cb;
+ inqparm.getpin_cb_arg = getpin_cb_arg;
+ snprintf (line, DIM(line)-1, "PKDECRYPT %s", keyid);
+ line[DIM(line)-1] = 0;
+ rc = assuan_transact (scd_ctx, line,
+ membuf_data_cb, &data,
+ inq_needpin, &inqparm,
+ NULL, NULL);
+ if (rc)
+ {
+ xfree (get_membuf (&data, &len));
+ return map_assuan_err (rc);
+ }
+ *r_buf = get_membuf (&data, r_buflen);
+ if (!*r_buf)
+ return GNUPG_Out_Of_Core;
+
+ return 0;
+}
+