Add support for LCD detection on pinpad devices.
* Update IOCTL definitions to PC/SC part 10 v2.02.05 * Return SC_SUCCESS instead of 0 if returning SC_ codes. * Detect the presence of a display with FEATURE_IFD_PIN_PROPERTIES Tested with patched CCID driver on OS X, with SPR532 (no display) and OK3821 (with display) Known CCID reader with a display: ATMEL_AT91SO.txt: wLcdLayout: 0x0210 CardMan3821.txt: wLcdLayout: 0x0210 Kobil_EMV_CAP.txt: wLcdLayout: 0x0210 Xiring_XI-SIGN.txt: wLcdLayout: 0x020C Xiring_XI-SIGN_6000.txt: wLcdLayout: 0x020C git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3666 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
3b0faecbb1
commit
9668f0aa33
|
@ -137,21 +137,27 @@ typedef LONG (PCSC_API *SCardListReaders_t)(SCARDCONTEXT hContext, LPCSTR mszGro
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TeleTrust Class 2 reader tags
|
* PC/SC v2.02.05 part 10 reader tags
|
||||||
*/
|
*/
|
||||||
#define CM_IOCTL_GET_FEATURE_REQUEST SCARD_CTL_CODE(3400)
|
#define CM_IOCTL_GET_FEATURE_REQUEST SCARD_CTL_CODE(3400)
|
||||||
|
|
||||||
#define FEATURE_VERIFY_PIN_START 0x01 /**< OMNIKEY Proposal */
|
#define FEATURE_VERIFY_PIN_START 0x01
|
||||||
#define FEATURE_VERIFY_PIN_FINISH 0x02 /**< OMNIKEY Proposal */
|
#define FEATURE_VERIFY_PIN_FINISH 0x02
|
||||||
#define FEATURE_MODIFY_PIN_START 0x03 /**< OMNIKEY Proposal */
|
#define FEATURE_MODIFY_PIN_START 0x03
|
||||||
#define FEATURE_MODIFY_PIN_FINISH 0x04 /**< OMNIKEY Proposal */
|
#define FEATURE_MODIFY_PIN_FINISH 0x04
|
||||||
#define FEATURE_GET_KEY_PRESSED 0x05 /**< OMNIKEY Proposal */
|
#define FEATURE_GET_KEY_PRESSED 0x05
|
||||||
#define FEATURE_VERIFY_PIN_DIRECT 0x06 /**< USB CCID PIN Verify */
|
#define FEATURE_VERIFY_PIN_DIRECT 0x06
|
||||||
#define FEATURE_MODIFY_PIN_DIRECT 0x07 /**< USB CCID PIN Modify */
|
#define FEATURE_MODIFY_PIN_DIRECT 0x07
|
||||||
#define FEATURE_MCT_READERDIRECT 0x08 /**< KOBIL Proposal */
|
#define FEATURE_MCT_READERDIRECT 0x08
|
||||||
#define FEATURE_MCT_UNIVERSAL 0x09 /**< KOBIL Proposal */
|
#define FEATURE_MCT_UNIVERSAL 0x09
|
||||||
#define FEATURE_IFD_PIN_PROP 0x0A /**< Gemplus Proposal */
|
#define FEATURE_IFD_PIN_PROPERTIES 0x0A
|
||||||
#define FEATURE_ABORT 0x0B /**< SCM Proposal */
|
#define FEATURE_ABORT 0x0B
|
||||||
|
#define FEATURE_SET_SPE_MESSAGE 0x0C
|
||||||
|
#define FEATURE_VERIFY_PIN_DIRECT_APP_ID 0x0D
|
||||||
|
#define FEATURE_MODIFY_PIN_DIRECT_APP_ID 0x0E
|
||||||
|
#define FEATURE_WRITE_DISPLAY 0x0F
|
||||||
|
#define FEATURE_GET_KEY 0x10
|
||||||
|
#define FEATURE_IFD_DISPLAY_PROPERTIES 0x11
|
||||||
|
|
||||||
/* structures used (but not defined) in PCSC Part 10 revision 2.01.02:
|
/* structures used (but not defined) in PCSC Part 10 revision 2.01.02:
|
||||||
* "IFDs with Secure Pin Entry Capabilities" */
|
* "IFDs with Secure Pin Entry Capabilities" */
|
||||||
|
@ -235,6 +241,14 @@ typedef struct
|
||||||
uint8_t abData[1]; /**< Data to send to the ICC */
|
uint8_t abData[1]; /**< Data to send to the ICC */
|
||||||
} PIN_MODIFY_STRUCTURE;
|
} PIN_MODIFY_STRUCTURE;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t wLcdLayout; /**< display characteristics */
|
||||||
|
uint16_t wLcdMaxCharacters;
|
||||||
|
uint16_t wLcdMaxLines;
|
||||||
|
uint8_t bEntryValidationCondition;
|
||||||
|
uint8_t bTimeOut2;
|
||||||
|
} PIN_PROPERTIES_STRUCTURE;
|
||||||
|
|
||||||
/* restore default structure elements alignment */
|
/* restore default structure elements alignment */
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
|
@ -207,7 +207,7 @@ static int pcsc_internal_transmit(sc_reader_t *reader, sc_slot_info_t *slot,
|
||||||
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
|
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
|
||||||
*recvsize = dwRecvLength;
|
*recvsize = dwRecvLength;
|
||||||
|
|
||||||
return 0;
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pcsc_transmit(sc_reader_t *reader, sc_slot_info_t *slot,
|
static int pcsc_transmit(sc_reader_t *reader, sc_slot_info_t *slot,
|
||||||
|
@ -422,7 +422,7 @@ static int pcsc_wait_for_event(sc_reader_t **readers,
|
||||||
*event |= SC_EVENT_CARD_REMOVED;
|
*event |= SC_EVENT_CARD_REMOVED;
|
||||||
if (*event) {
|
if (*event) {
|
||||||
*reader = i;
|
*reader = i;
|
||||||
return 0;
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No match - copy the state so pcscd knows
|
/* No match - copy the state so pcscd knows
|
||||||
|
@ -509,7 +509,7 @@ static int pcsc_connect(sc_reader_t *reader, sc_slot_info_t *slot)
|
||||||
struct pcsc_slot_data *pslot = GET_SLOT_DATA(slot);
|
struct pcsc_slot_data *pslot = GET_SLOT_DATA(slot);
|
||||||
int r;
|
int r;
|
||||||
u8 feature_buf[256];
|
u8 feature_buf[256];
|
||||||
DWORD i, feature_len;
|
DWORD i, feature_len, display_ioctl;
|
||||||
PCSC_TLV_STRUCTURE *pcsc_tlv;
|
PCSC_TLV_STRUCTURE *pcsc_tlv;
|
||||||
|
|
||||||
r = refresh_slot_attributes(reader, slot);
|
r = refresh_slot_attributes(reader, slot);
|
||||||
|
@ -575,6 +575,8 @@ static int pcsc_connect(sc_reader_t *reader, sc_slot_info_t *slot)
|
||||||
pslot->modify_ioctl_start = ntohl(pcsc_tlv[i].value);
|
pslot->modify_ioctl_start = ntohl(pcsc_tlv[i].value);
|
||||||
} else if (pcsc_tlv[i].tag == FEATURE_MODIFY_PIN_FINISH) {
|
} else if (pcsc_tlv[i].tag == FEATURE_MODIFY_PIN_FINISH) {
|
||||||
pslot->modify_ioctl_finish = ntohl(pcsc_tlv[i].value);
|
pslot->modify_ioctl_finish = ntohl(pcsc_tlv[i].value);
|
||||||
|
} else if (pcsc_tlv[i].tag == FEATURE_IFD_PIN_PROPERTIES) {
|
||||||
|
display_ioctl = ntohl(pcsc_tlv[i].value);
|
||||||
} else {
|
} else {
|
||||||
sc_debug(reader->ctx, "Reader pinpad feature: %02x not supported", pcsc_tlv[i].tag);
|
sc_debug(reader->ctx, "Reader pinpad feature: %02x not supported", pcsc_tlv[i].tag);
|
||||||
}
|
}
|
||||||
|
@ -599,7 +601,25 @@ static int pcsc_connect(sc_reader_t *reader, sc_slot_info_t *slot)
|
||||||
} else {
|
} else {
|
||||||
sc_debug(reader->ctx, "%s %s", log_text, log_disabled);
|
sc_debug(reader->ctx, "%s %s", log_text, log_disabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (display_ioctl) {
|
||||||
|
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
|
||||||
|
size_t rcount = sizeof(rbuf);
|
||||||
|
r = pcsc_internal_transmit(reader, slot, NULL, 0, rbuf, &rcount, display_ioctl);
|
||||||
|
if (r == SC_SUCCESS) {
|
||||||
|
if (rcount != sizeof(PIN_PROPERTIES_STRUCTURE)) {
|
||||||
|
PIN_PROPERTIES_STRUCTURE *caps = (PIN_PROPERTIES_STRUCTURE *)rbuf;
|
||||||
|
if (caps->wLcdLayout > 0) {
|
||||||
|
sc_debug(reader->ctx, "Reader has a display: %04X", caps->wLcdLayout);
|
||||||
|
slot->capabilities |= SC_SLOT_CAP_DISPLAY;
|
||||||
|
} else
|
||||||
|
sc_debug(reader->ctx, "Reader does not have a display.");
|
||||||
|
} else {
|
||||||
|
sc_debug(reader->ctx, "Returned PIN properties structure has bad length (%d)", rcount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
sc_debug(reader->ctx, "Inconsistent TLV from reader!");
|
sc_debug(reader->ctx, "Inconsistent TLV from reader!");
|
||||||
} else {
|
} else {
|
||||||
|
@ -838,7 +858,7 @@ static int pcsc_finish(sc_context_t *ctx, void *prv_data)
|
||||||
free(gpriv);
|
free(gpriv);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data)
|
static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data)
|
||||||
|
|
Loading…
Reference in New Issue