Merge pull request #500 from frankmorgner/reader_max_data_size
honour PC/SC pt 10 dwMaxAPDUDataSize
This commit is contained in:
commit
c48afdbfcb
|
@ -254,12 +254,12 @@ int sc_connect_card(sc_reader_t *reader, sc_card_t **card_out)
|
||||||
* Note that zero means no limitations at all.
|
* Note that zero means no limitations at all.
|
||||||
*/
|
*/
|
||||||
if ((card->max_recv_size == 0) ||
|
if ((card->max_recv_size == 0) ||
|
||||||
((reader->driver->max_recv_size != 0) && (reader->driver->max_recv_size < card->max_recv_size)))
|
((reader->max_recv_size != 0) && (reader->max_recv_size < card->max_recv_size)))
|
||||||
card->max_recv_size = reader->driver->max_recv_size;
|
card->max_recv_size = reader->max_recv_size;
|
||||||
|
|
||||||
if ((card->max_send_size == 0) ||
|
if ((card->max_send_size == 0) ||
|
||||||
((reader->driver->max_send_size != 0) && (reader->driver->max_send_size < card->max_send_size)))
|
((reader->max_send_size != 0) && (reader->max_send_size < card->max_send_size)))
|
||||||
card->max_send_size = reader->driver->max_send_size;
|
card->max_send_size = reader->max_send_size;
|
||||||
|
|
||||||
sc_log(ctx, "card info name:'%s', type:%i, flags:0x%X, max_send/recv_size:%i/%i",
|
sc_log(ctx, "card info name:'%s', type:%i, flags:0x%X, max_send/recv_size:%i/%i",
|
||||||
card->name, card->type, card->flags, card->max_send_size, card->max_recv_size);
|
card->name, card->type, card->flags, card->max_send_size, card->max_recv_size);
|
||||||
|
|
|
@ -289,15 +289,28 @@ static void load_reader_driver_options(sc_context_t *ctx)
|
||||||
{
|
{
|
||||||
struct sc_reader_driver *driver = ctx->reader_driver;
|
struct sc_reader_driver *driver = ctx->reader_driver;
|
||||||
scconf_block *conf_block = NULL;
|
scconf_block *conf_block = NULL;
|
||||||
|
sc_reader_t *reader;
|
||||||
driver->max_send_size = 0;
|
int max_send_size;
|
||||||
driver->max_recv_size = 0;
|
int max_recv_size;
|
||||||
|
|
||||||
conf_block = sc_get_conf_block(ctx, "reader_driver", driver->short_name, 1);
|
conf_block = sc_get_conf_block(ctx, "reader_driver", driver->short_name, 1);
|
||||||
|
|
||||||
if (conf_block != NULL) {
|
if (conf_block != NULL) {
|
||||||
driver->max_send_size = scconf_get_int(conf_block, "max_send_size", driver->max_send_size);
|
max_send_size = scconf_get_int(conf_block, "max_send_size", -1);
|
||||||
driver->max_recv_size = scconf_get_int(conf_block, "max_recv_size", driver->max_recv_size);
|
max_recv_size = scconf_get_int(conf_block, "max_recv_size", -1);
|
||||||
|
if (max_send_size >= 0 || max_recv_size >= 0) {
|
||||||
|
if (list_iterator_start(&ctx->readers)) {
|
||||||
|
reader = list_iterator_next(&ctx->readers);
|
||||||
|
while (reader) {
|
||||||
|
if (max_send_size >= 0)
|
||||||
|
reader->max_send_size = max_send_size;
|
||||||
|
if (max_recv_size >= 0)
|
||||||
|
reader->max_recv_size = max_recv_size;
|
||||||
|
reader = list_iterator_next(&ctx->readers);
|
||||||
|
}
|
||||||
|
list_iterator_stop(&ctx->readers);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -739,7 +752,6 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm)
|
||||||
ctx->reader_driver = sc_get_openct_driver();
|
ctx->reader_driver = sc_get_openct_driver();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
load_reader_driver_options(ctx);
|
|
||||||
r = ctx->reader_driver->ops->init(ctx);
|
r = ctx->reader_driver->ops->init(ctx);
|
||||||
if (r != SC_SUCCESS) {
|
if (r != SC_SUCCESS) {
|
||||||
sc_release_context(ctx);
|
sc_release_context(ctx);
|
||||||
|
@ -755,6 +767,7 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm)
|
||||||
}
|
}
|
||||||
del_drvs(&opts);
|
del_drvs(&opts);
|
||||||
sc_ctx_detect_readers(ctx);
|
sc_ctx_detect_readers(ctx);
|
||||||
|
load_reader_driver_options(ctx);
|
||||||
*ctx_out = ctx;
|
*ctx_out = ctx;
|
||||||
|
|
||||||
return SC_SUCCESS;
|
return SC_SUCCESS;
|
||||||
|
|
|
@ -200,6 +200,7 @@ typedef LONG (PCSC_API *SCardGetAttrib_t)(SCARDHANDLE hCard, DWORD dwAttrId,\
|
||||||
#define PCSCv2_PART10_PROPERTY_bMaxPINSize 7
|
#define PCSCv2_PART10_PROPERTY_bMaxPINSize 7
|
||||||
#define PCSCv2_PART10_PROPERTY_sFirmwareID 8
|
#define PCSCv2_PART10_PROPERTY_sFirmwareID 8
|
||||||
#define PCSCv2_PART10_PROPERTY_bPPDUSupport 9
|
#define PCSCv2_PART10_PROPERTY_bPPDUSupport 9
|
||||||
|
#define PCSCv2_PART10_PROPERTY_dwMaxAPDUDataSize 10
|
||||||
|
|
||||||
/* structures used (but not defined) in PCSC Part 10:
|
/* structures used (but not defined) in PCSC Part 10:
|
||||||
* "IFDs with Secure Pin Entry Capabilities" */
|
* "IFDs with Secure Pin Entry Capabilities" */
|
||||||
|
|
|
@ -275,8 +275,6 @@ struct sc_reader_driver {
|
||||||
const char *short_name;
|
const char *short_name;
|
||||||
struct sc_reader_operations *ops;
|
struct sc_reader_operations *ops;
|
||||||
|
|
||||||
size_t max_send_size; /* Max Lc supported by the reader layer */
|
|
||||||
size_t max_recv_size; /* Mac Le supported by the reader layer */
|
|
||||||
void *dll;
|
void *dll;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -305,6 +303,8 @@ typedef struct sc_reader {
|
||||||
|
|
||||||
unsigned long flags, capabilities;
|
unsigned long flags, capabilities;
|
||||||
unsigned int supported_protocols, active_protocol;
|
unsigned int supported_protocols, active_protocol;
|
||||||
|
size_t max_send_size; /* Max Lc supported by the reader layer */
|
||||||
|
size_t max_recv_size; /* Mac Le supported by the reader layer */
|
||||||
|
|
||||||
struct sc_atr atr;
|
struct sc_atr atr;
|
||||||
struct _atr_info {
|
struct _atr_info {
|
||||||
|
|
|
@ -620,7 +620,7 @@ static struct sc_reader_driver pcsc_drv = {
|
||||||
"PC/SC reader",
|
"PC/SC reader",
|
||||||
"pcsc",
|
"pcsc",
|
||||||
&pcsc_ops,
|
&pcsc_ops,
|
||||||
0, 0, NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static int pcsc_init(sc_context_t *ctx)
|
static int pcsc_init(sc_context_t *ctx)
|
||||||
|
@ -817,6 +817,50 @@ err:
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
part10_find_property_by_tag(unsigned char buffer[], int length,
|
||||||
|
int tag_searched);
|
||||||
|
/**
|
||||||
|
* @brief Detects reader's maximum data size
|
||||||
|
*
|
||||||
|
* @param reader reader to probe (\c get_tlv_properties must be initialized)
|
||||||
|
*
|
||||||
|
* @return maximum data size
|
||||||
|
*/
|
||||||
|
static size_t part10_detect_max_data(sc_reader_t *reader, SCARDHANDLE card_handle)
|
||||||
|
{
|
||||||
|
u8 rbuf[256];
|
||||||
|
DWORD rcount = sizeof rbuf;
|
||||||
|
struct pcsc_private_data *priv;
|
||||||
|
/* 0 means no limitations */
|
||||||
|
size_t max_data = 0;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (!reader)
|
||||||
|
goto err;
|
||||||
|
priv = GET_PRIV_DATA(reader);
|
||||||
|
if (!priv)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
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!");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = part10_find_property_by_tag(rbuf, rcount,
|
||||||
|
PCSCv2_PART10_PROPERTY_dwMaxAPDUDataSize);
|
||||||
|
if (r >= 0)
|
||||||
|
max_data = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
err:
|
||||||
|
return max_data;
|
||||||
|
}
|
||||||
|
|
||||||
static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) {
|
static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) {
|
||||||
sc_context_t *ctx = reader->ctx;
|
sc_context_t *ctx = reader->ctx;
|
||||||
struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *) ctx->reader_drv_data;
|
struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *) ctx->reader_drv_data;
|
||||||
|
@ -940,6 +984,12 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle)
|
||||||
sc_log(ctx, "%s %s", log_text, log_disabled);
|
sc_log(ctx, "%s %s", log_text, log_disabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
reader->max_recv_size = reader->max_send_size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pcsc_detect_readers(sc_context_t *ctx)
|
static int pcsc_detect_readers(sc_context_t *ctx)
|
||||||
|
|
Loading…
Reference in New Issue