- added defines for pin modification
- debugging apdu and rapdu there where they are created - splitted pin block operations into several functions git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@26 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
350
ccid/ccid.c
350
ccid/ccid.c
@@ -58,15 +58,10 @@ ccid_desc = {
|
|||||||
|
|
||||||
int ccid_initialize(int reader_id, int verbose)
|
int ccid_initialize(int reader_id, int verbose)
|
||||||
{
|
{
|
||||||
sc_context_param_t ctx_param;
|
|
||||||
int sc_result;
|
int sc_result;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
memset(&ctx_param, 0, sizeof(ctx_param));
|
sc_result = sc_context_create(&ctx, NULL);
|
||||||
//ctx_param.ver = 0;
|
|
||||||
//ctx_param.app_name = app_name;
|
|
||||||
|
|
||||||
sc_result = sc_context_create(&ctx, &ctx_param);
|
|
||||||
if (sc_result < 0) {
|
if (sc_result < 0) {
|
||||||
fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(sc_result));
|
fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(sc_result));
|
||||||
return 0;
|
return 0;
|
||||||
@@ -126,11 +121,11 @@ int ccid_shutdown()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int build_apdu(const __u8 *buf, size_t len, sc_apdu_t *apdu)
|
int build_apdu(const __u8 *buf, size_t len, sc_apdu_t *apdu)
|
||||||
{
|
{
|
||||||
const __u8 *p;
|
const __u8 *p;
|
||||||
size_t len0;
|
size_t len0;
|
||||||
|
char dbg[40];
|
||||||
|
|
||||||
len0 = len;
|
len0 = len;
|
||||||
if (len < 4) {
|
if (len < 4) {
|
||||||
@@ -183,13 +178,22 @@ int build_apdu(const __u8 *buf, size_t len, sc_apdu_t *apdu)
|
|||||||
|
|
||||||
apdu->flags = SC_APDU_FLAGS_NO_GET_RESP|SC_APDU_FLAGS_NO_RETRY_WL;
|
apdu->flags = SC_APDU_FLAGS_NO_GET_RESP|SC_APDU_FLAGS_NO_RETRY_WL;
|
||||||
|
|
||||||
|
snprintf(dbg, sizeof dbg, "APDU, %d byte(s):\tins=%02x p1=%02x p2=%02x",
|
||||||
|
(unsigned int) len, apdu->ins, apdu->p1, apdu->p2);
|
||||||
|
sc_ui_display_debug(ctx, dbg);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_rapdu(sc_apdu_t *apdu, size_t slot, __u8 **buf, size_t *resplen, int *sc_result)
|
int get_rapdu(sc_apdu_t *apdu, size_t slot, __u8 **buf, size_t *resplen, int *sc_result)
|
||||||
{
|
{
|
||||||
if (!apdu || !buf || !resplen || slot > sizeof card_in_slot || !sc_result)
|
char dbg[40];
|
||||||
|
|
||||||
|
if (!apdu || !buf || !resplen || slot > sizeof card_in_slot || !sc_result) {
|
||||||
|
if (sc_result)
|
||||||
|
*sc_result = SC_ERROR_INVALID_ARGUMENTS;
|
||||||
goto err;
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
apdu->resplen = apdu->le;
|
apdu->resplen = apdu->le;
|
||||||
/* Get two more bytes to later use as return buffer including sw1 and sw2 */
|
/* Get two more bytes to later use as return buffer including sw1 and sw2 */
|
||||||
@@ -215,6 +219,10 @@ int get_rapdu(sc_apdu_t *apdu, size_t slot, __u8 **buf, size_t *resplen, int *sc
|
|||||||
*buf = apdu->resp;
|
*buf = apdu->resp;
|
||||||
*resplen = apdu->resplen + sizeof(__u8) + sizeof(__u8);
|
*resplen = apdu->resplen + sizeof(__u8) + sizeof(__u8);
|
||||||
|
|
||||||
|
snprintf(dbg, sizeof dbg, "R-APDU, %d byte(s):\tsw1=%02x sw2=%02x",
|
||||||
|
(unsigned int) *resplen, apdu->sw1, apdu->sw2);
|
||||||
|
sc_ui_display_debug(ctx, dbg);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
@@ -403,7 +411,6 @@ RDR_to_PC_DataBlock_t
|
|||||||
perform_PC_to_RDR_XfrBlock(const PC_to_RDR_XfrBlock_t request, const __u8*
|
perform_PC_to_RDR_XfrBlock(const PC_to_RDR_XfrBlock_t request, const __u8*
|
||||||
abDataIn, __u8** abDataOut)
|
abDataIn, __u8** abDataOut)
|
||||||
{
|
{
|
||||||
char buf[50];
|
|
||||||
int sc_result;
|
int sc_result;
|
||||||
size_t resplen = 0;
|
size_t resplen = 0;
|
||||||
sc_apdu_t apdu;
|
sc_apdu_t apdu;
|
||||||
@@ -420,20 +427,12 @@ perform_PC_to_RDR_XfrBlock(const PC_to_RDR_XfrBlock_t request, const __u8*
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(buf, sizeof buf, "APDU, %d byte(s):\tins=%02x p1=%02x p2=%02x lc=%02x le=%02x",
|
get_rapdu(&apdu, request.bSlot, abDataOut, &resplen, &sc_result);
|
||||||
request.dwLength, apdu.ins, apdu.p1, apdu.p2, (int) apdu.lc, (int) apdu.le);
|
|
||||||
sc_ui_display_debug(ctx, buf);
|
|
||||||
|
|
||||||
if (!get_rapdu(&apdu, request.bSlot, abDataOut, &resplen, &sc_result))
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
snprintf(buf, sizeof buf, "RAPDU, %d byte(s):\tsw1=%02x sw2=%02x",
|
|
||||||
(int) resplen, apdu.sw1, apdu.sw2);
|
|
||||||
sc_ui_display_debug(ctx, buf);
|
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if (sc_result < 0)
|
if (sc_result < 0)
|
||||||
sc_ui_display_error(ctx, sc_strerror(sc_result));
|
sc_ui_display_error(ctx, sc_strerror(sc_result));
|
||||||
|
|
||||||
return get_RDR_to_PC_DataBlock(request.bSlot, request.bSeq,
|
return get_RDR_to_PC_DataBlock(request.bSlot, request.bSeq,
|
||||||
sc_result, __cpu_to_le32(resplen));
|
sc_result, __cpu_to_le32(resplen));
|
||||||
}
|
}
|
||||||
@@ -536,11 +535,165 @@ perform_PC_to_RDR_GetParamters(const PC_to_RDR_GetParameters_t request,
|
|||||||
SC_SUCCESS, abProtocolDataStructure);
|
SC_SUCCESS, abProtocolDataStructure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
get_effective_offset(uint8_t system_units, uint8_t off, size_t *eff_off,
|
||||||
|
int *sc_result)
|
||||||
|
{
|
||||||
|
if (!eff_off || !sc_result) {
|
||||||
|
if (sc_result)
|
||||||
|
*sc_result = SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (system_units)
|
||||||
|
*eff_off = off;
|
||||||
|
else
|
||||||
|
if (off == 0)
|
||||||
|
*eff_off = 0;
|
||||||
|
else if (off == 8)
|
||||||
|
*eff_off = 1;
|
||||||
|
|
||||||
|
*sc_result = SC_SUCCESS;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
write_pin_length(sc_apdu_t *apdu, const struct sc_pin_cmd_pin *pin,
|
||||||
|
uint8_t system_units, uint8_t length_size, int *sc_result)
|
||||||
|
{
|
||||||
|
u8 *p;
|
||||||
|
|
||||||
|
if (!apdu || !apdu->data || !pin || apdu->datalen <= pin->length_offset || !sc_result) {
|
||||||
|
if (sc_result)
|
||||||
|
*sc_result = SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length_size) {
|
||||||
|
if (length_size != 8) {
|
||||||
|
*sc_result = SC_ERROR_NOT_SUPPORTED;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
p = (u8 *) apdu->data;
|
||||||
|
p[pin->length_offset] = pin->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
*sc_result = SC_SUCCESS;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
encode_pin(u8 *buf, size_t buf_len, struct sc_pin_cmd_pin *pin,
|
||||||
|
uint8_t encoding, int *sc_result)
|
||||||
|
{
|
||||||
|
const u8 *p;
|
||||||
|
|
||||||
|
if (!pin || !buf || !sc_result) {
|
||||||
|
if (sc_result)
|
||||||
|
*sc_result = SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encoding == CCID_PIN_ENCODING_BIN) {
|
||||||
|
for (p = pin->data; *p && buf_len>0; buf++, p++, buf_len--) {
|
||||||
|
switch (*p) {
|
||||||
|
case '0':
|
||||||
|
*buf = 0x00;
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
*buf = 0x01;
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
*buf = 0x02;
|
||||||
|
break;
|
||||||
|
case '3':
|
||||||
|
*buf = 0x03;
|
||||||
|
break;
|
||||||
|
case '4':
|
||||||
|
*buf = 0x04;
|
||||||
|
break;
|
||||||
|
case '5':
|
||||||
|
*buf = 0x05;
|
||||||
|
break;
|
||||||
|
case '6':
|
||||||
|
*buf = 0x06;
|
||||||
|
break;
|
||||||
|
case '7':
|
||||||
|
*buf = 0x07;
|
||||||
|
break;
|
||||||
|
case '8':
|
||||||
|
*buf = 0x08;
|
||||||
|
break;
|
||||||
|
case '9':
|
||||||
|
*buf = 0x09;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*sc_result = SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!buf_len && *p) {
|
||||||
|
*sc_result = SC_ERROR_OUT_OF_MEMORY;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*sc_result = SC_SUCCESS;
|
||||||
|
} else {
|
||||||
|
if (encoding == CCID_PIN_ENCODING_BCD)
|
||||||
|
pin->encoding = SC_PIN_ENCODING_BCD;
|
||||||
|
else if (encoding == CCID_PIN_ENCODING_ASCII)
|
||||||
|
pin->encoding = SC_PIN_ENCODING_ASCII;
|
||||||
|
else {
|
||||||
|
*sc_result = SC_ERROR_NOT_SUPPORTED;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*sc_result = sc_build_pin(buf, buf_len, pin, 0);
|
||||||
|
|
||||||
|
if (*sc_result < 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
write_pin(sc_apdu_t *apdu, struct sc_pin_cmd_pin *pin, uint8_t blocksize,
|
||||||
|
uint8_t justify_right, uint8_t encoding, int *sc_result)
|
||||||
|
{
|
||||||
|
/* offset due to right alignment */
|
||||||
|
uint8_t justify_offset;
|
||||||
|
|
||||||
|
if (!apdu || !pin || !sc_result) {
|
||||||
|
if (sc_result)
|
||||||
|
*sc_result = SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (justify_right) {
|
||||||
|
if (encoding == CCID_PIN_ENCODING_BCD) {
|
||||||
|
if (pin->len % 2) {
|
||||||
|
*sc_result = SC_ERROR_NOT_SUPPORTED;
|
||||||
|
return 0;
|
||||||
|
} else
|
||||||
|
justify_offset = blocksize - pin->len/2;
|
||||||
|
} else
|
||||||
|
justify_offset = blocksize - pin->len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
justify_offset = 0;
|
||||||
|
|
||||||
|
return encode_pin((u8 *) apdu->data + justify_offset,
|
||||||
|
blocksize - justify_offset, pin, encoding, sc_result);
|
||||||
|
}
|
||||||
|
|
||||||
RDR_to_PC_DataBlock_t
|
RDR_to_PC_DataBlock_t
|
||||||
perform_PC_to_RDR_Secure(const PC_to_RDR_Secure_t request,
|
perform_PC_to_RDR_Secure(const PC_to_RDR_Secure_t request,
|
||||||
const __u8* abData, __u8** abDataOut)
|
const __u8* abData, __u8** abDataOut)
|
||||||
{
|
{
|
||||||
char buf[50];
|
char dbg[256];
|
||||||
int sc_result = SC_SUCCESS;
|
int sc_result = SC_SUCCESS;
|
||||||
size_t resplen = 0;
|
size_t resplen = 0;
|
||||||
sc_apdu_t apdu;
|
sc_apdu_t apdu;
|
||||||
@@ -603,21 +756,33 @@ perform_PC_to_RDR_Secure(const PC_to_RDR_Secure_t request,
|
|||||||
}
|
}
|
||||||
apdu.sensitive = 1;
|
apdu.sensitive = 1;
|
||||||
|
|
||||||
snprintf(buf, sizeof buf, "APDU, %d byte(s):\tins=%02x p1=%02x p2=%02x lc=%02x le=%02x",
|
|
||||||
request.dwLength, apdu.ins, apdu.p1, apdu.p2, (int) apdu.lc, (int) apdu.le);
|
|
||||||
sc_ui_display_debug(ctx, buf);
|
|
||||||
|
|
||||||
__u8 *p;
|
|
||||||
/* Note: offset and length_offset are relative to the first databyte */
|
|
||||||
pin.min_length = wPINMaxExtraDigit >> 8;
|
pin.min_length = wPINMaxExtraDigit >> 8;
|
||||||
pin.max_length = wPINMaxExtraDigit & 0x00ff;
|
pin.max_length = wPINMaxExtraDigit & 0x00ff;
|
||||||
pin.offset = (bmFormatString >> 3) & 0xf;
|
uint8_t system_units = bmFormatString & CCID_PIN_UNITS_BYTES;
|
||||||
uint8_t system_units_bytes = bmFormatString & CCID_PIN_UNITS_BYTES;
|
uint8_t pin_offset = (bmFormatString >> 3) & 0xf;
|
||||||
|
uint8_t length_offset = bmPINLengthFormat & 0xf;
|
||||||
|
uint8_t length_size = bmPINBlockString >> 4;
|
||||||
uint8_t justify_right = bmFormatString & CCID_PIN_JUSTIFY_RIGHT;
|
uint8_t justify_right = bmFormatString & CCID_PIN_JUSTIFY_RIGHT;
|
||||||
uint8_t encoding = bmFormatString & 2;
|
uint8_t encoding = bmFormatString & 2;
|
||||||
uint8_t offset_length = bmPINBlockString >> 4;
|
|
||||||
uint8_t blocksize = bmPINBlockString & 0xf;
|
uint8_t blocksize = bmPINBlockString & 0xf;
|
||||||
uint8_t length_shift = bmPINLengthFormat & 0xf;
|
|
||||||
|
snprintf(dbg, sizeof dbg,
|
||||||
|
"PIN block (%d bytes) proberties:\n"
|
||||||
|
"\tminimum %d, maximum %d PIN digits\n"
|
||||||
|
"\t%s PIN encoding, %s justification\n"
|
||||||
|
"\tsystem units are %s\n"
|
||||||
|
"\twrite PIN length on %d bits with %d system units offset\n"
|
||||||
|
"\tPIN offset is %d %s\n",
|
||||||
|
blocksize, (unsigned int) pin.min_length,
|
||||||
|
(unsigned int) pin.max_length,
|
||||||
|
encoding == CCID_PIN_ENCODING_BIN ? "binary" :
|
||||||
|
encoding == CCID_PIN_ENCODING_BCD ? "BCD" :
|
||||||
|
encoding == CCID_PIN_ENCODING_ASCII ? "ASCII" :"unknown",
|
||||||
|
justify_right ? "right" : "left",
|
||||||
|
system_units ? "bytes" : "bits",
|
||||||
|
length_size, length_offset, pin_offset,
|
||||||
|
modify ? "bytes" : "system units");
|
||||||
|
sc_ui_display_debug(ctx, dbg);
|
||||||
|
|
||||||
/* get the PIN */
|
/* get the PIN */
|
||||||
hints.prompt = "PIN Verification";
|
hints.prompt = "PIN Verification";
|
||||||
@@ -628,122 +793,27 @@ perform_PC_to_RDR_Secure(const PC_to_RDR_Secure_t request,
|
|||||||
if (sc_result < 0)
|
if (sc_result < 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
/* check length of PIN */
|
/* set and check length of PIN */
|
||||||
pin.len = strlen((char *) pin.data);
|
pin.len = strlen((char *) pin.data);
|
||||||
if (pin.len > pin.max_length || pin.len < pin.min_length) {
|
if ((pin.max_length && pin.len > pin.max_length)
|
||||||
|
|| pin.len < pin.min_length) {
|
||||||
sc_result = SC_ERROR_PIN_CODE_INCORRECT;
|
sc_result = SC_ERROR_PIN_CODE_INCORRECT;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write length of PIN */
|
/* Note: pin.offset and pin.length_offset are relative to the first
|
||||||
if (offset_length) {
|
* databyte */
|
||||||
if (offset_length == 8) {
|
if (!get_effective_offset(system_units, pin_offset, &pin.offset,
|
||||||
if (system_units_bytes) {
|
&sc_result)
|
||||||
pin.length_offset = length_shift;
|
|| !get_effective_offset(system_units, length_offset,
|
||||||
} else {
|
&pin.length_offset, &sc_result)
|
||||||
if (length_shift == 0)
|
|| !write_pin_length(&apdu, &pin, system_units, length_size,
|
||||||
pin.length_offset = 0;
|
&sc_result)
|
||||||
if (length_shift == 8)
|
|| !write_pin(&apdu, &pin, blocksize, justify_right, encoding,
|
||||||
pin.length_offset = 1;
|
&sc_result)
|
||||||
else {
|
|| !get_rapdu(&apdu, request.bSlot, abDataOut, &resplen,
|
||||||
|
&sc_result))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
|
||||||
}
|
|
||||||
p = (u8 *) apdu.data + pin.length_offset;
|
|
||||||
*p = pin.len;
|
|
||||||
} else {
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* offset due to right alignment */
|
|
||||||
uint8_t justify_offset;
|
|
||||||
if (justify_right) {
|
|
||||||
if (encoding == CCID_PIN_ENCODING_BCD) {
|
|
||||||
if (pin.len % 2)
|
|
||||||
goto err;
|
|
||||||
else
|
|
||||||
justify_offset = pin.len/2;
|
|
||||||
} else
|
|
||||||
justify_offset = blocksize - pin.len;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
justify_offset = 0;
|
|
||||||
|
|
||||||
/* set p to the first byte where to write the PIN */
|
|
||||||
if (system_units_bytes) {
|
|
||||||
p = (u8 *) apdu.data + pin.offset + justify_offset;
|
|
||||||
} else {
|
|
||||||
if (pin.offset == 0)
|
|
||||||
p = (u8 *) apdu.data + justify_offset;
|
|
||||||
else if (pin.offset == 8)
|
|
||||||
p = (u8 *) apdu.data + 1 + justify_offset;
|
|
||||||
else {
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* encode and write the pin into the APDU */
|
|
||||||
const u8 *ppin;
|
|
||||||
if (encoding == CCID_PIN_ENCODING_BIN) {
|
|
||||||
for (ppin = pin.data; *ppin; p++, ppin++) {
|
|
||||||
switch (*ppin) {
|
|
||||||
case '0':
|
|
||||||
*p = 0x00;
|
|
||||||
break;
|
|
||||||
case '1':
|
|
||||||
*p = 0x01;
|
|
||||||
break;
|
|
||||||
case '2':
|
|
||||||
*p = 0x02;
|
|
||||||
break;
|
|
||||||
case '3':
|
|
||||||
*p = 0x03;
|
|
||||||
break;
|
|
||||||
case '4':
|
|
||||||
*p = 0x04;
|
|
||||||
break;
|
|
||||||
case '5':
|
|
||||||
*p = 0x05;
|
|
||||||
break;
|
|
||||||
case '6':
|
|
||||||
*p = 0x06;
|
|
||||||
break;
|
|
||||||
case '7':
|
|
||||||
*p = 0x07;
|
|
||||||
break;
|
|
||||||
case '8':
|
|
||||||
*p = 0x08;
|
|
||||||
break;
|
|
||||||
case '9':
|
|
||||||
*p = 0x09;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sc_result = SC_ERROR_PIN_CODE_INCORRECT;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (encoding == CCID_PIN_ENCODING_BCD)
|
|
||||||
pin.encoding = SC_PIN_ENCODING_BCD;
|
|
||||||
else if (encoding == CCID_PIN_ENCODING_ASCII)
|
|
||||||
pin.encoding = SC_PIN_ENCODING_ASCII;
|
|
||||||
else {
|
|
||||||
sc_result = SC_ERROR_NOT_SUPPORTED;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
sc_result = sc_build_pin(p, abPINApdu - p, &pin, 0);
|
|
||||||
if (sc_result < 0) {
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!get_rapdu(&apdu, request.bSlot, abDataOut, &resplen, &sc_result))
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
snprintf(buf, sizeof buf, "RAPDU, %d byte(s):\tsw1=%02x sw2=%02x",
|
|
||||||
(int) resplen, apdu.sw1, apdu.sw2);
|
|
||||||
sc_ui_display_debug(ctx, buf);
|
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if (sc_result < 0)
|
if (sc_result < 0)
|
||||||
|
|||||||
@@ -69,6 +69,9 @@ extern "C" {
|
|||||||
#define CCID_PIN_UNITS_BYTES 0x80
|
#define CCID_PIN_UNITS_BYTES 0x80
|
||||||
#define CCID_PIN_JUSTIFY_RIGHT 0x04
|
#define CCID_PIN_JUSTIFY_RIGHT 0x04
|
||||||
|
|
||||||
|
#define CCID_PIN_CONFIRM_NEW 0x01
|
||||||
|
#define CCID_PIN_INSERT_OLD 0x02
|
||||||
|
|
||||||
#define CCID_SLOTS_UNCHANGED 0x00
|
#define CCID_SLOTS_UNCHANGED 0x00
|
||||||
#define CCID_SLOT1_CARD_PRESENT 0x01
|
#define CCID_SLOT1_CARD_PRESENT 0x01
|
||||||
#define CCID_SLOT1_CHANGED 0x02
|
#define CCID_SLOT1_CHANGED 0x02
|
||||||
|
|||||||
@@ -54,8 +54,8 @@
|
|||||||
#define DRIVER_PRODUCT_NUM 0x3010 /* KOBIL Class 3 Reader */
|
#define DRIVER_PRODUCT_NUM 0x3010 /* KOBIL Class 3 Reader */
|
||||||
static int vendorid = DRIVER_VENDOR_NUM;
|
static int vendorid = DRIVER_VENDOR_NUM;
|
||||||
static int productid = DRIVER_PRODUCT_NUM;
|
static int productid = DRIVER_PRODUCT_NUM;
|
||||||
static int verbose = 1;
|
static int verbose = 0;
|
||||||
static int debug = 1;
|
static int debug = 0;
|
||||||
static int dohid = 0;
|
static int dohid = 0;
|
||||||
static int doint = 0;
|
static int doint = 0;
|
||||||
int usb_reader_num = 0;
|
int usb_reader_num = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user