reactivate handling of `0` for max_recv/send_size

The special value still needs to be handled for commands that are issued
during card initialization. This especially concerns T=0 cards that need
to use iso_get_response.

fixes #533
regression of 85b79a3332
This commit is contained in:
Frank Morgner 2015-08-26 02:39:28 +02:00
parent 4df35b922c
commit 2d9802308f
6 changed files with 65 additions and 31 deletions

View File

@ -581,7 +581,7 @@ int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu)
* bytes using command chaining */
size_t len = apdu->datalen;
const u8 *buf = apdu->data;
size_t max_send_size = card->max_send_size;
size_t max_send_size = sc_get_max_send_size(card);
while (len != 0) {
size_t plen;

View File

@ -871,7 +871,7 @@ static int dnie_compose_and_send_apdu(sc_card_t *card, const u8 *path, size_t pa
apdu.lc = pathlen;
apdu.data = path;
apdu.datalen = pathlen;
apdu.le = card->max_recv_size;
apdu.le = sc_get_max_recv_size(card);
if (p1 == 3)
apdu.cse= SC_APDU_CASE_1;

View File

@ -249,7 +249,7 @@ static int sc_hsm_read_binary(sc_card_t *card,
cmdbuff[2] = (idx >> 8) & 0xFF;
cmdbuff[3] = idx & 0xFF;
assert(count <= card->max_recv_size);
assert(count <= sc_get_max_recv_size(card));
sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0xB1, 0x00, 0x00);
apdu.data = cmdbuff;
apdu.datalen = 4;

View File

@ -135,6 +135,54 @@ static void sc_card_free(sc_card_t *card)
free(card);
}
size_t sc_get_max_recv_size(const sc_card_t *card)
{
size_t max_recv_size;
assert(card != NULL && card->reader != NULL);
max_recv_size = card->max_recv_size;
/* initialize max_recv_size to a meaningfull value */
if (card->caps & SC_CARD_CAP_APDU_EXT) {
if (!max_recv_size)
max_recv_size = 65536;
} else {
if (!max_recv_size)
max_recv_size = 256;
}
/* Override card limitations with reader limitations. */
if (card->reader->max_recv_size != 0
&& (card->reader->max_recv_size < card->max_recv_size))
max_recv_size = card->reader->max_recv_size;
return max_recv_size;
}
size_t sc_get_max_send_size(const sc_card_t *card)
{
size_t max_send_size;
assert(card != NULL && card->reader != NULL);
max_send_size = card->max_send_size;
/* initialize max_send_size to a meaningfull value */
if (card->caps & SC_CARD_CAP_APDU_EXT) {
if (!max_send_size)
max_send_size = 65535;
} else {
if (!max_send_size)
max_send_size = 255;
}
/* Override card limitations with reader limitations. */
if (card->reader->max_send_size != 0
&& (card->reader->max_send_size < card->max_send_size))
max_send_size = card->reader->max_send_size;
return max_send_size;
}
int sc_connect_card(sc_reader_t *reader, sc_card_t **card_out)
{
sc_card_t *card;
@ -252,25 +300,8 @@ int sc_connect_card(sc_reader_t *reader, sc_card_t **card_out)
card->name = card->driver->name;
/* initialize max_send_size/max_recv_size to a meaningfull value */
if (card->caps & SC_CARD_CAP_APDU_EXT) {
if (!card->max_send_size)
card->max_send_size = 65535;
if (!card->max_recv_size)
card->max_recv_size = 65536;
} else {
if (!card->max_send_size)
card->max_send_size = 255;
if (!card->max_recv_size)
card->max_recv_size = 256;
}
/* Override card limitations with reader limitations. */
if (reader->max_recv_size != 0
&& (reader->max_recv_size < card->max_recv_size))
card->max_recv_size = reader->max_recv_size;
if (reader->max_send_size != 0
&& (reader->max_send_size < card->max_send_size))
card->max_send_size = reader->max_send_size;
card->max_recv_size = sc_get_max_recv_size(card);
card->max_send_size = sc_get_max_send_size(card);
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);
@ -489,7 +520,7 @@ int sc_delete_file(sc_card_t *card, const sc_path_t *path)
int sc_read_binary(sc_card_t *card, unsigned int idx,
unsigned char *buf, size_t count, unsigned long flags)
{
size_t max_le = card->max_recv_size;
size_t max_le = sc_get_max_recv_size(card);
int r;
assert(card != NULL && card->ops != NULL && buf != NULL);
@ -539,7 +570,7 @@ int sc_read_binary(sc_card_t *card, unsigned int idx,
int sc_write_binary(sc_card_t *card, unsigned int idx,
const u8 *buf, size_t count, unsigned long flags)
{
size_t max_lc = card->max_send_size;
size_t max_lc = sc_get_max_send_size(card);
int r;
assert(card != NULL && card->ops != NULL && buf != NULL);
@ -582,7 +613,7 @@ int sc_write_binary(sc_card_t *card, unsigned int idx,
int sc_update_binary(sc_card_t *card, unsigned int idx,
const u8 *buf, size_t count, unsigned long flags)
{
size_t max_lc = card->max_send_size;
size_t max_lc = sc_get_max_send_size(card);
int r;
assert(card != NULL && card->ops != NULL && buf != NULL);

View File

@ -35,15 +35,15 @@ static void fixup_transceive_length(const struct sc_card *card,
{
assert(card != NULL && apdu != NULL);
if (apdu->lc > card->max_send_size) {
if (apdu->lc > sc_get_max_send_size(card)) {
/* The lower layers will automatically do chaining */
apdu->flags |= SC_APDU_FLAGS_CHAINING;
}
if (apdu->le > card->max_recv_size) {
if (apdu->le > sc_get_max_recv_size(card)) {
/* The lower layers will automatically do a GET RESPONSE, if possible.
* All other workarounds must be carried out by the upper layers. */
apdu->le = card->max_recv_size;
apdu->le = sc_get_max_recv_size(card);
}
}
@ -526,7 +526,7 @@ iso7816_select_file(struct sc_card *card, const struct sc_path *in_path, struct
apdu.p2 = 0; /* first record, return FCI */
apdu.resp = buf;
apdu.resplen = sizeof(buf);
apdu.le = card->max_recv_size < 256 ? card->max_recv_size : 256;
apdu.le = sc_get_max_recv_size(card) < 256 ? sc_get_max_recv_size(card) : 256;
}
else {
apdu.p2 = 0x0C; /* first record, return nothing */
@ -719,8 +719,8 @@ iso7816_get_response(struct sc_card *card, size_t *count, u8 *buf)
size_t rlen;
/* request at most max_recv_size bytes */
if (*count > card->max_recv_size)
rlen = card->max_recv_size;
if (*count > sc_get_max_recv_size(card))
rlen = sc_get_max_recv_size(card);
else
rlen = *count;

View File

@ -910,6 +910,9 @@ int sc_lock(struct sc_card *card);
*/
int sc_unlock(struct sc_card *card);
size_t sc_get_max_recv_size(const sc_card_t *card);
size_t sc_get_max_send_size(const sc_card_t *card);
/********************************************************************/
/* ISO 7816-4 related functions */