Beispiel #1
0
/* 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);
}
Beispiel #2
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;
}