diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index a2703f57..7b325756 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -258,10 +258,25 @@ static void load_reader_driver_options(sc_context_t *ctx, driver->max_recv_size = SC_APDU_CHOP_SIZE; if (conf_block != NULL) { const scconf_list *list; - + const char *forcestr; + if (scconf_get_bool(conf_block, "apdu_fix", 0)) driver->apdu_masquerade |= SC_APDU_MASQUERADE_4AS3; - + /* protocol force in action, addon by -mp */ + forcestr=scconf_get_str(conf_block, "force_protocol",NULL); + if (forcestr){ + sc_debug(ctx,"Protocol force in action : %s",forcestr); + if (!strcmp(forcestr,"t0")) + driver->forced_protocol = SC_PROTO_T0; + else if (!strcmp(forcestr,"t1")) + driver->forced_protocol = SC_PROTO_T1; + else if (!strcmp(forcestr,"raw")) + driver->forced_protocol = SC_PROTO_RAW; + else + sc_error(ctx,"Unknown protocol: %s in force_protocol; ignored.",forcestr); + } else + driver->forced_protocol = 0; + list = scconf_find_list(conf_block, "apdu_masquerade"); if (list) driver->apdu_masquerade = 0; diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index f3e80bf0..0d37e467 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -260,6 +260,7 @@ struct sc_reader_driver { size_t max_send_size, max_recv_size; int apdu_masquerade; + unsigned int forced_protocol; }; #define SC_APDU_MASQUERADE_NONE 0x00 #define SC_APDU_MASQUERADE_4AS3 0x01 diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 7019ed8f..84d75d73 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -378,7 +378,7 @@ static int pcsc_wait_for_event(struct sc_reader **readers, static int pcsc_connect(struct sc_reader *reader, struct sc_slot_info *slot) { - DWORD active_proto; + DWORD active_proto, protocol; SCARDHANDLE card_handle; LONG rv; struct pcsc_private_data *priv = GET_PRIV_DATA(reader); @@ -390,9 +390,15 @@ static int pcsc_connect(struct sc_reader *reader, struct sc_slot_info *slot) return r; if (!(slot->flags & SC_SLOT_CARD_PRESENT)) return SC_ERROR_CARD_NOT_PRESENT; - rv = SCardConnect(priv->pcsc_ctx, priv->reader_name, - SCARD_SHARE_SHARED, SCARD_PROTOCOL_ANY, - &card_handle, &active_proto); + + /* force a protocol, addon by -mp */ + if (reader->driver->forced_protocol) { + protocol = opensc_proto_to_pcsc(reader->driver->forced_protocol); + } else + protocol = SCARD_PROTOCOL_ANY; + + rv = SCardConnect(priv->pcsc_ctx, priv->reader_name, + SCARD_SHARE_SHARED, protocol, &card_handle, &active_proto); if (rv != 0) { PCSC_ERROR(reader->ctx, "SCardConnect failed", rv); return pcsc_ret_to_error(rv);