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:
martin 2009-03-21 11:09:12 +00:00
parent 3b0faecbb1
commit 9668f0aa33
2 changed files with 51 additions and 17 deletions

View File

@ -137,21 +137,27 @@ typedef LONG (PCSC_API *SCardListReaders_t)(SCARDCONTEXT hContext, LPCSTR mszGro
#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 FEATURE_VERIFY_PIN_START 0x01 /**< OMNIKEY Proposal */
#define FEATURE_VERIFY_PIN_FINISH 0x02 /**< OMNIKEY Proposal */
#define FEATURE_MODIFY_PIN_START 0x03 /**< OMNIKEY Proposal */
#define FEATURE_MODIFY_PIN_FINISH 0x04 /**< OMNIKEY Proposal */
#define FEATURE_GET_KEY_PRESSED 0x05 /**< OMNIKEY Proposal */
#define FEATURE_VERIFY_PIN_DIRECT 0x06 /**< USB CCID PIN Verify */
#define FEATURE_MODIFY_PIN_DIRECT 0x07 /**< USB CCID PIN Modify */
#define FEATURE_MCT_READERDIRECT 0x08 /**< KOBIL Proposal */
#define FEATURE_MCT_UNIVERSAL 0x09 /**< KOBIL Proposal */
#define FEATURE_IFD_PIN_PROP 0x0A /**< Gemplus Proposal */
#define FEATURE_ABORT 0x0B /**< SCM Proposal */
#define FEATURE_VERIFY_PIN_START 0x01
#define FEATURE_VERIFY_PIN_FINISH 0x02
#define FEATURE_MODIFY_PIN_START 0x03
#define FEATURE_MODIFY_PIN_FINISH 0x04
#define FEATURE_GET_KEY_PRESSED 0x05
#define FEATURE_VERIFY_PIN_DIRECT 0x06
#define FEATURE_MODIFY_PIN_DIRECT 0x07
#define FEATURE_MCT_READERDIRECT 0x08
#define FEATURE_MCT_UNIVERSAL 0x09
#define FEATURE_IFD_PIN_PROPERTIES 0x0A
#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:
* "IFDs with Secure Pin Entry Capabilities" */
@ -235,6 +241,14 @@ typedef struct
uint8_t abData[1]; /**< Data to send to the ICC */
} 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 */
#ifdef __APPLE__
#pragma pack()

View File

@ -207,7 +207,7 @@ static int pcsc_internal_transmit(sc_reader_t *reader, sc_slot_info_t *slot,
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
*recvsize = dwRecvLength;
return 0;
return SC_SUCCESS;
}
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;
if (*event) {
*reader = i;
return 0;
return SC_SUCCESS;
}
/* 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);
int r;
u8 feature_buf[256];
DWORD i, feature_len;
DWORD i, feature_len, display_ioctl;
PCSC_TLV_STRUCTURE *pcsc_tlv;
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);
} else if (pcsc_tlv[i].tag == FEATURE_MODIFY_PIN_FINISH) {
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 {
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 {
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
sc_debug(reader->ctx, "Inconsistent TLV from reader!");
} else {
@ -838,7 +858,7 @@ static int pcsc_finish(sc_context_t *ctx, void *prv_data)
free(gpriv);
}
return 0;
return SC_SUCCESS;
}
static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data)