⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iso7816-2.c

📁 ISO7816智能卡开发的一写代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    }  return 0;}/* Perform a PUT DATA command on card in SLOT.  Write DATA of length   DATALEN to TAG. */gpg_error_tiso7816_put_data (int slot, int tag,                  const unsigned char *data, size_t datalen){  int sw;  sw = apdu_send_simple (slot, 0x00, CMD_PUT_DATA,                         ((tag >> 8) & 0xff), (tag & 0xff),                         datalen, (const char*)data);  return map_sw (sw);}/* Manage Security Environment.  This is a weird operation and there   is no easy abstraction for it.  Furthermore, some card seem to have   a different interpreation of 7816-8 and thus we resort to let the   caller decide what to do. */gpg_error_tiso7816_manage_security_env (int slot, int p1, int p2,                             const unsigned char *data, size_t datalen){  int sw;  if (p1 < 0 || p1 > 255 || p2 < 0 || p2 > 255 )    return gpg_error (GPG_ERR_INV_VALUE);  sw = apdu_send_simple (slot, 0x00, CMD_MSE, p1, p2,                          data? datalen : -1, (const char*)data);  return map_sw (sw);}/* Perform the security operation COMPUTE DIGITAL SIGANTURE.  On   success 0 is returned and the data is availavle in a newly   allocated buffer stored at RESULT with its length stored at   RESULTLEN. */gpg_error_tiso7816_compute_ds (int slot, const unsigned char *data, size_t datalen,                    unsigned char **result, size_t *resultlen){  int sw;  if (!data || !datalen || !result || !resultlen)    return gpg_error (GPG_ERR_INV_VALUE);  *result = NULL;  *resultlen = 0;  sw = apdu_send (slot, 0x00, CMD_PSO, 0x9E, 0x9A, datalen, (const char*)data,                  result, resultlen);  if (sw != SW_SUCCESS)    {      /* Make sure that pending buffers are released. */      xfree (*result);      *result = NULL;      *resultlen = 0;      return map_sw (sw);    }  return 0;}/* Perform the security operation DECIPHER.  PADIND is the padding   indicator to be used.  It should be 0 if no padding is required, a   value of -1 suppresses the padding byte.  On success 0 is returned   and the plaintext is available in a newly allocated buffer stored   at RESULT with its length stored at RESULTLEN. */gpg_error_tiso7816_decipher (int slot, const unsigned char *data, size_t datalen,                  int padind, unsigned char **result, size_t *resultlen){  int sw;  unsigned char *buf;  if (!data || !datalen || !result || !resultlen)    return gpg_error (GPG_ERR_INV_VALUE);  *result = NULL;  *resultlen = 0;  if (padind >= 0)    {      /* We need to prepend the padding indicator. */      buf = xtrymalloc (datalen + 1);      if (!buf)        return gpg_error (gpg_err_code_from_errno (errno));      *buf = padind; /* Padding indicator. */      memcpy (buf+1, data, datalen);      sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86,                      datalen+1, (char*)buf,                      result, resultlen);      xfree (buf);    }  else    {      sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86,                      datalen, (const char *)data,                      result, resultlen);    }  if (sw != SW_SUCCESS)    {      /* Make sure that pending buffers are released. */      xfree (*result);      *result = NULL;      *resultlen = 0;      return map_sw (sw);    }  return 0;}gpg_error_tiso7816_internal_authenticate (int slot,                               const unsigned char *data, size_t datalen,                               unsigned char **result, size_t *resultlen){  int sw;  if (!data || !datalen || !result || !resultlen)    return gpg_error (GPG_ERR_INV_VALUE);  *result = NULL;  *resultlen = 0;  sw = apdu_send (slot, 0x00, CMD_INTERNAL_AUTHENTICATE, 0, 0,                  datalen, (const char*)data,  result, resultlen);  if (sw != SW_SUCCESS)    {      /* Make sure that pending buffers are released. */      xfree (*result);      *result = NULL;      *resultlen = 0;      return map_sw (sw);    }  return 0;}static gpg_error_tdo_generate_keypair (int slot, int readonly,                  const unsigned char *data, size_t datalen,                  unsigned char **result, size_t *resultlen){  int sw;  if (!data || !datalen || !result || !resultlen)    return gpg_error (GPG_ERR_INV_VALUE);  *result = NULL;  *resultlen = 0;  sw = apdu_send (slot, 0x00, CMD_GENERATE_KEYPAIR, readonly? 0x81:0x80, 0,                  datalen, (const char*)data,  result, resultlen);  if (sw != SW_SUCCESS)    {      /* Make sure that pending buffers are released. */      xfree (*result);      *result = NULL;      *resultlen = 0;      return map_sw (sw);    }  return 0;}gpg_error_tiso7816_generate_keypair (int slot,                          const unsigned char *data, size_t datalen,                          unsigned char **result, size_t *resultlen){  return do_generate_keypair (slot, 0, data, datalen, result, resultlen);}gpg_error_tiso7816_read_public_key (int slot,                          const unsigned char *data, size_t datalen,                          unsigned char **result, size_t *resultlen){  return do_generate_keypair (slot, 1, data, datalen, result, resultlen);}gpg_error_tiso7816_get_challenge (int slot, int length, unsigned char *buffer){  int sw;  unsigned char *result;  size_t resultlen, n;  if (!buffer || length < 1)    return gpg_error (GPG_ERR_INV_VALUE);  do    {      result = NULL;      n = length > 254? 254 : length;      sw = apdu_send_le (slot, 0x00, CMD_GET_CHALLENGE, 0, 0, -1, NULL,                         n,                         &result, &resultlen);      if (sw != SW_SUCCESS)        {          /* Make sure that pending buffers are released. */          xfree (result);          return map_sw (sw);        }      if (resultlen > n)        resultlen = n;      memcpy (buffer, result, resultlen);      buffer += resultlen;      length -= resultlen;      xfree (result);    }  while (length > 0);  return 0;}/* Perform a READ BINARY command requesting a maximum of NMAX bytes   from OFFSET.  With NMAX = 0 the entire file is read. The result is   stored in a newly allocated buffer at the address passed by RESULT.   Returns the length of this data at the address of RESULTLEN. */gpg_error_tiso7816_read_binary (int slot, size_t offset, size_t nmax,                     unsigned char **result, size_t *resultlen){  int sw;  unsigned char *buffer;  size_t bufferlen;  int read_all = !nmax;  size_t n;  if (!result || !resultlen)    return gpg_error (GPG_ERR_INV_VALUE);  *result = NULL;  *resultlen = 0;  /* We can only encode 15 bits in p0,p1 to indicate an offset. Thus     we check for this limit. */  if (offset > 32767)    return gpg_error (GPG_ERR_INV_VALUE);  do    {      buffer = NULL;      bufferlen = 0;      /* Note, that we to set N to 254 due to problems either with the         ccid driver or some TCOS cards.  It actually should be 0         which is the official ISO value to read a variable length         object. */      if (read_all || nmax > 254)        n = 254;      else        n = nmax;      sw = apdu_send_le (slot, 0x00, CMD_READ_BINARY,                         ((offset>>8) & 0xff), (offset & 0xff) , -1, NULL,                         n, &buffer, &bufferlen);      if ( SW_EXACT_LENGTH_P(sw) )        {          n = (sw & 0x00ff);          sw = apdu_send_le (slot, 0x00, CMD_READ_BINARY,                             ((offset>>8) & 0xff), (offset & 0xff) , -1, NULL,                             n, &buffer, &bufferlen);        }      if (*result && sw == SW_BAD_P0_P1)        {          /* Bad Parameter means that the offset is outside of the             EF. When reading all data we take this as an indication             for EOF.  */          break;        }      if (sw != SW_SUCCESS && sw != SW_EOF_REACHED)        {          /* Make sure that pending buffers are released. */          xfree (buffer);          xfree (*result);          *result = NULL;          *resultlen = 0;          return map_sw (sw);        }      if (*result) /* Need to extend the buffer. */        {          unsigned char *p = xtryrealloc (*result, *resultlen + bufferlen);          if (!p)            {              gpg_error_t err = gpg_error_from_syserror ();              xfree (buffer);              xfree (*result);              *result = NULL;              *resultlen = 0;              return err;            }          *result = p;          memcpy (*result + *resultlen, buffer, bufferlen);          *resultlen += bufferlen;          xfree (buffer);          buffer = NULL;        }      else /* Transfer the buffer into our result. */        {          *result = buffer;          *resultlen = bufferlen;        }      offset += bufferlen;      if (offset > 32767)        break; /* We simply truncate the result for too large                  files. */      if (nmax > bufferlen)        nmax -= bufferlen;      else        nmax = 0;    }  while ((read_all && sw != SW_EOF_REACHED) || (!read_all && nmax));    return 0;}/* Perform a READ RECORD command. RECNO gives the record number to   read with 0 indicating the current record.  RECCOUNT must be 1 (not   all cards support reading of more than one record).  SHORT_EF   should be 0 to read the current EF or contain a short EF. The   result is stored in a newly allocated buffer at the address passed   by RESULT.  Returns the length of this data at the address of   RESULTLEN. */gpg_error_tiso7816_read_record (int slot, int recno, int reccount, int short_ef,                     unsigned char **result, size_t *resultlen){  int sw;  unsigned char *buffer;  size_t bufferlen;  if (!result || !resultlen)    return gpg_error (GPG_ERR_INV_VALUE);  *result = NULL;  *resultlen = 0;  /* We can only encode 15 bits in p0,p1 to indicate an offset. Thus     we check for this limit. */  if (recno < 0 || recno > 255 || reccount != 1      || short_ef < 0 || short_ef > 254 )    return gpg_error (GPG_ERR_INV_VALUE);  buffer = NULL;  bufferlen = 0;  /* Fixme: Either the ccid driver or the TCOS cards have problems     with an Le of 0. */  sw = apdu_send_le (slot, 0x00, CMD_READ_RECORD,                     recno,                      short_ef? short_ef : 0x04,                     -1, NULL,                     254, &buffer, &bufferlen);  if (sw != SW_SUCCESS && sw != SW_EOF_REACHED)    {      /* Make sure that pending buffers are released. */      xfree (buffer);      xfree (*result);      *result = NULL;      *resultlen = 0;      return map_sw (sw);    }  *result = buffer;  *resultlen = bufferlen;    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -