- added error reporting for several new SWs
- added check_sw function to sc_card_operations git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@211 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
709727d469
commit
262e5c2083
|
@ -256,7 +256,7 @@ static int select_file_id(struct sc_card *card, const u8 *buf, size_t buflen,
|
|||
apdu.resplen = 0;
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
r = sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
SC_TEST_RET(card->ctx, r, "Card returned error");
|
||||
|
||||
if (file == NULL)
|
||||
|
@ -349,7 +349,7 @@ static int flex_list_files(struct sc_card *card, u8 *buf, size_t buflen)
|
|||
return r;
|
||||
if (apdu.sw1 == 0x6A && apdu.sw2 == 0x82)
|
||||
break;
|
||||
r = sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
if (r)
|
||||
return r;
|
||||
if (apdu.resplen != 4) {
|
||||
|
@ -385,7 +385,7 @@ static int flex_delete_file(struct sc_card *card, const struct sc_path *path)
|
|||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
return sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
|
||||
return sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
}
|
||||
|
||||
static int acl_to_ac(unsigned int acl)
|
||||
|
@ -524,7 +524,7 @@ static int flex_create_file(struct sc_card *card, struct sc_file *file)
|
|||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
r = sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
SC_TEST_RET(card->ctx, r, "Card returned error");
|
||||
if (card->cache_valid) {
|
||||
u8 file_id[2];
|
||||
|
@ -598,7 +598,7 @@ static int flex_compute_signature(struct sc_card *card, const u8 *data,
|
|||
apdu.resp = sbuf;
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
r = sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
SC_TEST_RET(card->ctx, r, "Card returned error");
|
||||
for (i = 0; i < apdu.resplen; i++)
|
||||
out[i] = sbuf[apdu.resplen-1-i];
|
||||
|
@ -640,7 +640,7 @@ static int flex_verify(struct sc_card *card, unsigned int type, int ref,
|
|||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
if (apdu.sw1 == 0x63)
|
||||
return SC_ERROR_PIN_CODE_INCORRECT;
|
||||
return sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
|
||||
return sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
}
|
||||
|
||||
static const struct sc_card_driver * sc_get_driver(void)
|
||||
|
|
|
@ -144,7 +144,7 @@ gpk_finish(struct sc_card *card)
|
|||
|
||||
/*
|
||||
* Error code handling for the GPK4000.
|
||||
* sc_sw_to_errorcode doesn't seem to handle all of the
|
||||
* sc_check_sw doesn't seem to handle all of the
|
||||
* status words the GPK is capable of returning
|
||||
*/
|
||||
static int
|
||||
|
@ -171,7 +171,7 @@ gpk_sw_to_errorcode(struct sc_card *card, u8 sw1, u8 sw2)
|
|||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
}
|
||||
|
||||
return sc_sw_to_errorcode(card, sw1, sw2);
|
||||
return sc_check_sw(card, sw1, sw2);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -142,7 +142,7 @@ static int tcos_list_files(struct sc_card *card, u8 *buf, size_t buflen)
|
|||
apdu.le = 256;
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
r = sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
if (r == SC_ERROR_FILE_NOT_FOUND)
|
||||
continue;
|
||||
SC_TEST_RET(card->ctx, r, "Card returned error");
|
||||
|
|
|
@ -24,52 +24,10 @@
|
|||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int sc_sw_to_errorcode(struct sc_card *card, int sw1, int sw2)
|
||||
int sc_check_sw(struct sc_card *card, int sw1, int sw2)
|
||||
{
|
||||
if (sw1 != 0x90 || sw2 != 0)
|
||||
error(card->ctx, "card returned SW1=%02X, SW2=%02X\n", sw1, sw2);
|
||||
switch (sw1) {
|
||||
case 0x67:
|
||||
if (sw2 == 0)
|
||||
return SC_ERROR_WRONG_LENGTH;
|
||||
break;
|
||||
case 0x69:
|
||||
switch (sw2) {
|
||||
case 0x82:
|
||||
return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x6A:
|
||||
switch (sw2) {
|
||||
case 0x81:
|
||||
return SC_ERROR_NOT_SUPPORTED;
|
||||
case 0x82:
|
||||
return SC_ERROR_FILE_NOT_FOUND;
|
||||
case 0x83:
|
||||
return SC_ERROR_RECORD_NOT_FOUND;
|
||||
case 0x85:
|
||||
case 0x86:
|
||||
case 0x87:
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x6C:
|
||||
error(card->ctx, "incorrect length, right length is %d\n",
|
||||
sw2);
|
||||
return SC_ERROR_WRONG_LENGTH;
|
||||
case 0x6D:
|
||||
return SC_ERROR_NOT_SUPPORTED;
|
||||
case 0x6E:
|
||||
return SC_ERROR_UNKNOWN_SMARTCARD;
|
||||
case 0x90:
|
||||
if (sw2 == 0)
|
||||
return 0;
|
||||
}
|
||||
return SC_ERROR_UNKNOWN_REPLY;
|
||||
assert(card->ops->check_sw != NULL);
|
||||
return card->ops->check_sw(card, sw1, sw2);
|
||||
}
|
||||
|
||||
static int _sc_pcscret_to_error(long rv)
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#define SC_CARD_MAGIC 0x27182818
|
||||
|
||||
/* Internal use only */
|
||||
int sc_sw_to_errorcode(struct sc_card *card, int sw1, int sw2);
|
||||
int sc_check_sw(struct sc_card *card, int sw1, int sw2);
|
||||
size_t sc_count_bit_string_size(const void * buf, size_t bufsize);
|
||||
|
||||
/* Default timeout value for SCardGetStatusChange */
|
||||
|
|
|
@ -25,6 +25,78 @@
|
|||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
struct sc_card_error {
|
||||
int SWs;
|
||||
int errorno;
|
||||
const char *errorstr;
|
||||
};
|
||||
|
||||
const static struct sc_card_error iso7816_errors[] = {
|
||||
{ 0x6200, SC_ERROR_UNKNOWN_REPLY, "State of non-volatile memory unchanged" },
|
||||
{ 0x6281, SC_ERROR_UNKNOWN_REPLY, "Part of returned data may be corrupted" },
|
||||
{ 0x6282, SC_ERROR_UNKNOWN_REPLY, "End of file/record reached before reading Le bytes" },
|
||||
{ 0x6283, SC_ERROR_UNKNOWN_REPLY, "Selected file invalidated" },
|
||||
{ 0x6284, SC_ERROR_UNKNOWN_REPLY, "FCI not formatted according to 5.1.5" },
|
||||
|
||||
{ 0x6300, SC_ERROR_UNKNOWN_REPLY, "State of non-volatile memory changed" },
|
||||
{ 0x6381, SC_ERROR_UNKNOWN_REPLY, "File filled up by last write" },
|
||||
|
||||
{ 0x6581, SC_ERROR_UNKNOWN_REPLY, "Memory failure" },
|
||||
|
||||
{ 0x6700, SC_ERROR_WRONG_LENGTH, "Wrong length" },
|
||||
|
||||
{ 0x6800, SC_ERROR_UNKNOWN_REPLY, "Functions in CLA not supported" },
|
||||
{ 0x6881, SC_ERROR_UNKNOWN_REPLY, "Logical channel not supported" },
|
||||
{ 0x6882, SC_ERROR_UNKNOWN_REPLY, "Secure messaging not supported" },
|
||||
|
||||
{ 0x6900, SC_ERROR_UNKNOWN_REPLY, "Command not allowed" },
|
||||
{ 0x6981, SC_ERROR_UNKNOWN_REPLY, "Command incompatible with file structure" },
|
||||
{ 0x6982, SC_ERROR_SECURITY_STATUS_NOT_SATISFIED, "Security status not satisfied" },
|
||||
{ 0x6983, SC_ERROR_UNKNOWN_REPLY, "Authentication method blocked" },
|
||||
{ 0x6984, SC_ERROR_UNKNOWN_REPLY, "Referenced data invalidated" },
|
||||
{ 0x6985, SC_ERROR_UNKNOWN_REPLY, "Conditions of use not satisfied" },
|
||||
{ 0x6986, SC_ERROR_UNKNOWN_REPLY, "Command not allowed (no current EF)" },
|
||||
{ 0x6987, SC_ERROR_UNKNOWN_REPLY, "Expected SM data objects missing" },
|
||||
{ 0x6988, SC_ERROR_UNKNOWN_REPLY, "SM data objects incorrect" },
|
||||
|
||||
{ 0x6A00, SC_ERROR_UNKNOWN_REPLY, "Wrong parameter(s) P1-P2" },
|
||||
{ 0x6A80, SC_ERROR_UNKNOWN_REPLY, "Incorrect parameters in the data field" },
|
||||
{ 0x6A81, SC_ERROR_NOT_SUPPORTED, "Function not supported" },
|
||||
{ 0x6A82, SC_ERROR_FILE_NOT_FOUND, "File not found" },
|
||||
{ 0x6A83, SC_ERROR_RECORD_NOT_FOUND, "Record not found" },
|
||||
{ 0x6A84, SC_ERROR_UNKNOWN_REPLY, "Not enough memory space in the file" },
|
||||
{ 0x6A85, SC_ERROR_INVALID_ARGUMENTS, "Lc inconsistent with TLV structure" },
|
||||
{ 0x6A86, SC_ERROR_INVALID_ARGUMENTS, "Incorrect parameters P1-P2" },
|
||||
{ 0x6A87, SC_ERROR_INVALID_ARGUMENTS, "Lc inconsistent with P1-P2" },
|
||||
{ 0x6A88, SC_ERROR_UNKNOWN_REPLY, "Referenced data not found" },
|
||||
|
||||
{ 0x6B00, SC_ERROR_UNKNOWN_REPLY, "Wrong parameter(s) P1-P2" },
|
||||
{ 0x6D00, SC_ERROR_NOT_SUPPORTED, "Instruction code not supported or invalid" },
|
||||
{ 0x6E00, SC_ERROR_CLASS_NOT_SUPPORTED, "Class not supported" },
|
||||
{ 0x6F00, SC_ERROR_UNKNOWN_REPLY, "No precise diagnosis" }
|
||||
};
|
||||
|
||||
static int iso7816_check_sw(struct sc_card *card, int sw1, int sw2)
|
||||
{
|
||||
const int err_count = sizeof(iso7816_errors)/sizeof(iso7816_errors[0]);
|
||||
int i;
|
||||
|
||||
/* Handle special cases here */
|
||||
if (sw1 == 0x6C) {
|
||||
error(card->ctx, "Wrong length; correct length is %d\n", sw2);
|
||||
return SC_ERROR_WRONG_LENGTH;
|
||||
}
|
||||
if (sw1 == 0x90)
|
||||
return SC_NO_ERROR;
|
||||
for (i = 0; i < err_count; i++)
|
||||
if (iso7816_errors[i].SWs == ((sw1 << 8) | sw2)) {
|
||||
error(card->ctx, "%s\n", iso7816_errors[i].errorstr);
|
||||
return iso7816_errors[i].errorno;
|
||||
}
|
||||
error(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2);
|
||||
return SC_ERROR_UNKNOWN_REPLY;
|
||||
}
|
||||
|
||||
static int iso7816_read_binary(struct sc_card *card,
|
||||
unsigned int idx, u8 *buf, size_t count,
|
||||
unsigned long flags)
|
||||
|
@ -42,7 +114,7 @@ static int iso7816_read_binary(struct sc_card *card,
|
|||
r = sc_transmit_apdu(card, &apdu);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
if (apdu.resplen == 0)
|
||||
SC_FUNC_RETURN(card->ctx, 2, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
|
||||
SC_FUNC_RETURN(card->ctx, 2, sc_check_sw(card, apdu.sw1, apdu.sw2));
|
||||
memcpy(buf, recvbuf, apdu.resplen);
|
||||
|
||||
SC_FUNC_RETURN(card->ctx, 3, apdu.resplen);
|
||||
|
@ -68,7 +140,7 @@ static int iso7816_read_record(struct sc_card *card,
|
|||
r = sc_transmit_apdu(card, &apdu);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
if (apdu.resplen == 0)
|
||||
SC_FUNC_RETURN(card->ctx, 2, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
|
||||
SC_FUNC_RETURN(card->ctx, 2, sc_check_sw(card, apdu.sw1, apdu.sw2));
|
||||
memcpy(buf, recvbuf, apdu.resplen);
|
||||
|
||||
SC_FUNC_RETURN(card->ctx, 3, apdu.resplen);
|
||||
|
@ -93,7 +165,7 @@ static int iso7816_write_binary(struct sc_card *card,
|
|||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
SC_TEST_RET(card->ctx, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2),
|
||||
SC_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),
|
||||
"Card returned error");
|
||||
SC_FUNC_RETURN(card->ctx, 3, count);
|
||||
}
|
||||
|
@ -117,7 +189,7 @@ static int iso7816_update_binary(struct sc_card *card,
|
|||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
SC_TEST_RET(card->ctx, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2),
|
||||
SC_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),
|
||||
"Card returned error");
|
||||
SC_FUNC_RETURN(card->ctx, 3, count);
|
||||
}
|
||||
|
@ -284,10 +356,10 @@ static int iso7816_select_file(struct sc_card *card,
|
|||
if (file == NULL) {
|
||||
if (apdu.sw1 == 0x61)
|
||||
SC_FUNC_RETURN(card->ctx, 2, 0);
|
||||
SC_FUNC_RETURN(card->ctx, 2, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
|
||||
SC_FUNC_RETURN(card->ctx, 2, sc_check_sw(card, apdu.sw1, apdu.sw2));
|
||||
}
|
||||
|
||||
r = sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
if (r)
|
||||
SC_FUNC_RETURN(card->ctx, 2, r);
|
||||
|
||||
|
@ -322,7 +394,7 @@ static int iso7816_get_challenge(struct sc_card *card, u8 *rnd, size_t len)
|
|||
r = sc_transmit_apdu(card, &apdu);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
if (apdu.resplen != 8)
|
||||
return sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
|
||||
return sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
memcpy(rnd, apdu.resp, n);
|
||||
len -= n;
|
||||
rnd += n;
|
||||
|
@ -432,7 +504,7 @@ static int iso7816_create_file(struct sc_card *card, struct sc_file *file)
|
|||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
return sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
|
||||
return sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
}
|
||||
|
||||
static int iso7816_delete_file(struct sc_card *card, const struct sc_path *path)
|
||||
|
@ -455,7 +527,7 @@ static int iso7816_delete_file(struct sc_card *card, const struct sc_path *path)
|
|||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
return sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
|
||||
return sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
}
|
||||
|
||||
static int iso7816_list_files(struct sc_card *card, u8 *buf, size_t buflen)
|
||||
|
@ -470,7 +542,7 @@ static int iso7816_list_files(struct sc_card *card, u8 *buf, size_t buflen)
|
|||
r = sc_transmit_apdu(card, &apdu);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
if (apdu.resplen == 0)
|
||||
return sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
|
||||
return sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
return apdu.resplen;
|
||||
}
|
||||
|
||||
|
@ -505,7 +577,7 @@ static int iso7816_verify(struct sc_card *card, unsigned int type, int ref,
|
|||
*tries_left = apdu.sw2 & 0x0F;
|
||||
return SC_ERROR_PIN_CODE_INCORRECT;
|
||||
}
|
||||
return sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
|
||||
return sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
}
|
||||
|
||||
static int iso7816_set_security_env(struct sc_card *card,
|
||||
|
@ -569,7 +641,7 @@ static int iso7816_set_security_env(struct sc_card *card,
|
|||
sc_perror(card->ctx, r, "APDU transmit failed");
|
||||
goto err;
|
||||
}
|
||||
r = sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
if (r) {
|
||||
sc_perror(card->ctx, r, "Card returned error");
|
||||
goto err;
|
||||
|
@ -581,7 +653,7 @@ static int iso7816_set_security_env(struct sc_card *card,
|
|||
r = sc_transmit_apdu(card, &apdu);
|
||||
sc_unlock(card);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
return sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
|
||||
return sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
err:
|
||||
if (locked)
|
||||
sc_unlock(card);
|
||||
|
@ -601,7 +673,7 @@ static int iso7816_restore_security_env(struct sc_card *card, int se_num)
|
|||
apdu.resp = rbuf;
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
return sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
|
||||
return sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
}
|
||||
|
||||
static int iso7816_compute_signature(struct sc_card *card,
|
||||
|
@ -637,7 +709,7 @@ static int iso7816_compute_signature(struct sc_card *card,
|
|||
memcpy(out, apdu.resp, len);
|
||||
SC_FUNC_RETURN(card->ctx, 4, len);
|
||||
}
|
||||
SC_FUNC_RETURN(card->ctx, 4, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
|
||||
SC_FUNC_RETURN(card->ctx, 4, sc_check_sw(card, apdu.sw1, apdu.sw2));
|
||||
}
|
||||
|
||||
static int iso7816_change_reference_data(struct sc_card *card, unsigned int type,
|
||||
|
@ -676,7 +748,7 @@ static int iso7816_change_reference_data(struct sc_card *card, unsigned int type
|
|||
*tries_left = apdu.sw2 & 0x0F;
|
||||
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_PIN_CODE_INCORRECT);
|
||||
}
|
||||
return sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
|
||||
return sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
}
|
||||
|
||||
static int iso7816_reset_retry_counter(struct sc_card *card, unsigned int type, int ref,
|
||||
|
@ -718,7 +790,7 @@ static int iso7816_reset_retry_counter(struct sc_card *card, unsigned int type,
|
|||
r = sc_transmit_apdu(card, &apdu);
|
||||
memset(sbuf, 0, len);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
return sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
|
||||
return sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
}
|
||||
|
||||
static struct sc_card_operations iso_ops = {
|
||||
|
@ -757,6 +829,7 @@ const struct sc_card_driver * sc_get_iso7816_driver(void)
|
|||
iso_ops.compute_signature = iso7816_compute_signature;
|
||||
iso_ops.reset_retry_counter = iso7816_reset_retry_counter;
|
||||
iso_ops.change_reference_data = iso7816_change_reference_data;
|
||||
iso_ops.check_sw = iso7816_check_sw;
|
||||
}
|
||||
return &iso_driver;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#define SC_SUCCESS 0
|
||||
#define SC_NO_ERROR 0
|
||||
|
||||
#define SC_ERROR_MIN -1000
|
||||
#define SC_ERROR_UNKNOWN -1000
|
||||
|
@ -78,6 +79,7 @@ extern "C" {
|
|||
#define SC_ERROR_WRONG_LENGTH -1030
|
||||
#define SC_ERROR_RECORD_NOT_FOUND -1031
|
||||
#define SC_ERROR_INTERNAL -1032
|
||||
#define SC_ERROR_CLASS_NOT_SUPPORTED -1033
|
||||
|
||||
/* Different APDU cases */
|
||||
#define SC_APDU_CASE_NONE 0
|
||||
|
@ -157,7 +159,7 @@ extern "C" {
|
|||
#define SC_MAX_PATH_SIZE 16
|
||||
#define SC_MAX_PIN_SIZE 16
|
||||
#define SC_MAX_ATR_SIZE 33
|
||||
#define SC_MAX_SEC_ATTR_SIZE 16
|
||||
#define SC_MAX_SEC_ATTR_SIZE 20
|
||||
#define SC_MAX_PROP_ATTR_SIZE 16
|
||||
#define SC_MAX_OBJECT_ID_OCTETS 16
|
||||
#define SC_APDU_CHOP_SIZE 250
|
||||
|
@ -366,6 +368,8 @@ struct sc_card_operations {
|
|||
* writes the corresponding file identifiers to <buf>. Returns
|
||||
* the number of bytes stored. */
|
||||
int (*list_files)(struct sc_card *card, u8 *buf, size_t buflen);
|
||||
|
||||
int (*check_sw)(struct sc_card *card, int sw1, int sw2);
|
||||
};
|
||||
|
||||
struct sc_card_driver {
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#define SC_CARD_MAGIC 0x27182818
|
||||
|
||||
/* Internal use only */
|
||||
int sc_sw_to_errorcode(struct sc_card *card, int sw1, int sw2);
|
||||
int sc_check_sw(struct sc_card *card, int sw1, int sw2);
|
||||
size_t sc_count_bit_string_size(const void * buf, size_t bufsize);
|
||||
|
||||
/* Default timeout value for SCardGetStatusChange */
|
||||
|
|
|
@ -328,7 +328,8 @@ const char *sc_strerror(int error)
|
|||
"Card is invalid or cannot be handled",
|
||||
"Wrong length",
|
||||
"Record not found",
|
||||
"Internal error"
|
||||
"Internal error",
|
||||
"Invalid CLA byte in APDU",
|
||||
};
|
||||
int nr_errors = sizeof(errors) / sizeof(errors[0]);
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ int sc_decipher(struct sc_card *card,
|
|||
memcpy(out, apdu.resp, len);
|
||||
SC_FUNC_RETURN(card->ctx, 2, len);
|
||||
}
|
||||
SC_FUNC_RETURN(card->ctx, 2, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
|
||||
SC_FUNC_RETURN(card->ctx, 2, sc_check_sw(card, apdu.sw1, apdu.sw2));
|
||||
}
|
||||
|
||||
int sc_compute_signature(struct sc_card *card,
|
||||
|
|
Loading…
Reference in New Issue