/* Create a signature using the current card. MDALGO is either 0 or gives the digest algorithm. */ int agent_card_pksign (ctrl_t ctrl, const char *keyid, int (*getpin_cb)(void *, const char *, char*, size_t), void *getpin_cb_arg, int mdalgo, const unsigned char *indata, size_t indatalen, unsigned char **r_buf, size_t *r_buflen) { int rc; char line[ASSUAN_LINELENGTH]; membuf_t data; struct inq_needpin_s inqparm; *r_buf = NULL; rc = start_scd (ctrl); if (rc) return rc; if (indatalen*2 + 50 > DIM(line)) return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL)); bin2hex (indata, indatalen, stpcpy (line, "SETDATA ")); rc = assuan_transact (ctrl->scd_local->ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); if (rc) return unlock_scd (ctrl, rc); init_membuf (&data, 1024); inqparm.ctx = ctrl->scd_local->ctx; inqparm.getpin_cb = getpin_cb; inqparm.getpin_cb_arg = getpin_cb_arg; inqparm.passthru = 0; inqparm.any_inq_seen = 0; if (ctrl->use_auth_call) snprintf (line, sizeof line, "PKAUTH %s", keyid); else snprintf (line, sizeof line, "PKSIGN %s %s", hash_algo_option (mdalgo), keyid); rc = assuan_transact (ctrl->scd_local->ctx, line, membuf_data_cb, &data, inq_needpin, &inqparm, NULL, NULL); if (inqparm.any_inq_seen && (gpg_err_code(rc) == GPG_ERR_CANCELED || gpg_err_code(rc) == GPG_ERR_ASS_CANCELED)) rc = cancel_inquire (ctrl, rc); if (rc) { size_t len; xfree (get_membuf (&data, &len)); return unlock_scd (ctrl, rc); } *r_buf = get_membuf (&data, r_buflen); return unlock_scd (ctrl, 0); }
/* Send a sign command to the scdaemon via gpg-agent's pass thru mechanism. */ int agent_scd_pksign (const char *serialno, int hashalgo, const unsigned char *indata, size_t indatalen, unsigned char **r_buf, size_t *r_buflen) { int rc, i; char *p, line[ASSUAN_LINELENGTH]; membuf_t data; size_t len; /* Note, hashalgo is not yet used but hardwired to SHA1 in SCdaemon. */ *r_buf = NULL; *r_buflen = 0; rc = start_agent (1); if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT || gpg_err_code (rc) == GPG_ERR_NOT_SUPPORTED) rc = 0; /* We check later. */ if (rc) return rc; if (indatalen*2 + 50 > DIM(line)) return gpg_error (GPG_ERR_GENERAL); rc = select_openpgp (serialno); if (rc) return rc; sprintf (line, "SCD SETDATA "); p = line + strlen (line); for (i=0; i < indatalen ; i++, p += 2 ) sprintf (p, "%02X", indata[i]); rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); if (rc) return rc; init_membuf (&data, 1024); #if 0 if (!hashalgo) /* Temporary test hack. */ snprintf (line, DIM(line)-1, "SCD PKAUTH %s", serialno); else #endif snprintf (line, DIM(line)-1, "SCD PKSIGN %s %s", hash_algo_option (hashalgo), serialno); line[DIM(line)-1] = 0; rc = assuan_transact (agent_ctx, line, membuf_data_cb, &data, default_inq_cb, NULL, NULL, NULL); if (rc) { xfree (get_membuf (&data, &len)); } else *r_buf = get_membuf (&data, r_buflen); status_sc_op_failure (rc); return rc; }