diff --git a/src/libopensc/internal-winscard.h b/src/libopensc/internal-winscard.h index 2389d0c5..5cad5f54 100644 --- a/src/libopensc/internal-winscard.h +++ b/src/libopensc/internal-winscard.h @@ -201,6 +201,8 @@ typedef LONG (PCSC_API *SCardGetAttrib_t)(SCARDHANDLE hCard, DWORD dwAttrId,\ #define PCSCv2_PART10_PROPERTY_sFirmwareID 8 #define PCSCv2_PART10_PROPERTY_bPPDUSupport 9 #define PCSCv2_PART10_PROPERTY_dwMaxAPDUDataSize 10 +#define PCSCv2_PART10_PROPERTY_wIdVendor 11 +#define PCSCv2_PART10_PROPERTY_wIdProduct 12 /* structures used (but not defined) in PCSC Part 10: * "IFDs with Secure Pin Entry Capabilities" */ diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index b850db20..de137959 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -880,6 +880,46 @@ err: return max_data; } +static int part10_get_vendor_product(struct sc_reader *reader, + SCARDHANDLE card_handle, int *id_vendor, int *id_product) +{ + u8 rbuf[256]; + DWORD rcount = sizeof rbuf; + struct pcsc_private_data *priv; + /* 0 means no limitations */ + int this_vendor = -1, this_product = -1; + + if (!reader) + return SC_ERROR_INVALID_ARGUMENTS; + priv = GET_PRIV_DATA(reader); + if (!priv) + return SC_ERROR_INVALID_ARGUMENTS; + + if (priv->get_tlv_properties && priv->gpriv) { + if (SCARD_S_SUCCESS != priv->gpriv->SCardControl(card_handle, + priv->get_tlv_properties, NULL, 0, rbuf, sizeof(rbuf), + &rcount)) { + sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, + "PC/SC v2 part 10: Get TLV properties failed!"); + return SC_ERROR_TRANSMIT_FAILED; + } + + this_vendor = part10_find_property_by_tag(rbuf, rcount, + PCSCv2_PART10_PROPERTY_wIdVendor); + this_product = part10_find_property_by_tag(rbuf, rcount, + PCSCv2_PART10_PROPERTY_wIdProduct); + } + + sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "id_vendor=%04x id_product=%04x", this_vendor, this_product); + + if (id_vendor) + *id_vendor = this_vendor; + if (id_product) + *id_product = this_product; + + return SC_SUCCESS; +} + static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) { sc_context_t *ctx = reader->ctx; struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *) ctx->reader_drv_data; @@ -889,7 +929,6 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) PCSC_TLV_STRUCTURE *pcsc_tlv; LONG rv; const char *log_disabled = "but it's disabled in configuration file"; - const char *broken_readers[] = {"HP USB Smart Card Keyboard"}; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); @@ -957,14 +996,6 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) } } - /* Ignore advertised pinpad capability on readers known to be broken. Trac #340 */ - for (i = 0; i < sizeof(broken_readers)/sizeof(broken_readers[0]); i++) { - if (strstr(reader->name, broken_readers[i]) && (reader->capabilities & SC_READER_CAP_PIN_PAD)) { - sc_log(ctx, "%s has a broken pinpad, ignoring", reader->name); - reader->capabilities &= ~SC_READER_CAP_PIN_PAD; - } - } - /* Detect display */ if (priv->pin_properties_ioctl) { rcount = sizeof(rbuf); @@ -1004,10 +1035,15 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) } } - /* Set reader max_send_size and max_recv_size based on detected max_data */ if (priv->get_tlv_properties) { - reader->max_send_size = part10_detect_max_data(reader, card_handle); + /* Set reader max_send_size and max_recv_size based on + * detected max_data */ + reader->max_send_size = part10_detect_max_data(reader, + card_handle); reader->max_recv_size = reader->max_send_size; + + /* debug the product and vendor ID of the reader */ + part10_get_vendor_product(reader, card_handle, NULL, NULL); } }