don't always overwrite max_send_size/max_recv_size

If the reader announces extended length support, but the card driver
leaves max_send_size/max_recv_size at `0`, max_send_size/max_recv_size
previously would have been overwritten with the reader's size though the
card might not have set SC_CARD_CAP_APDU_EXT. This commit fixes this
behavior.

Additionally card->max_send_size/max_recv_size is always initialized to
a value different from 0 after the card initialization. This removes the
need to check for this special value in all subsequent calls.
This commit is contained in:
Frank Morgner 2015-08-04 23:06:25 +02:00
parent 27b64c5999
commit 85b79a3332
5 changed files with 29 additions and 37 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 > 0 ? card->max_send_size : 255;
size_t max_send_size = card->max_send_size;
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 > 0 ? card->max_recv_size : 256;
apdu.le = card->max_recv_size;
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 > 0 ? card->max_recv_size : 256));
assert(count <= card->max_recv_size);
sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0xB1, 0x00, 0x00);
apdu.data = cmdbuff;
apdu.datalen = 4;

View File

@ -251,15 +251,25 @@ int sc_connect_card(sc_reader_t *reader, sc_card_t **card_out)
if (card->name == NULL)
card->name = card->driver->name;
/* Override card limitations with reader limitations.
* Note that zero means no limitations at all.
*/
if ((card->max_recv_size == 0) ||
((reader->max_recv_size != 0) && (reader->max_recv_size < card->max_recv_size)))
card->max_recv_size = reader->max_recv_size;
/* 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;
}
if ((card->max_send_size == 0) ||
((reader->max_send_size != 0) && (reader->max_send_size < card->max_send_size)))
/* 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;
sc_log(ctx, "card info name:'%s', type:%i, flags:0x%X, max_send/recv_size:%i/%i",
@ -479,7 +489,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 > 0 ? card->max_recv_size : 256;
size_t max_le = card->max_recv_size;
int r;
assert(card != NULL && card->ops != NULL && buf != NULL);
@ -529,7 +539,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 > 0 ? card->max_send_size : 255;
size_t max_lc = card->max_send_size;
int r;
assert(card != NULL && card->ops != NULL && buf != NULL);
@ -572,7 +582,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 > 0 ? card->max_send_size : 255;
size_t max_lc = card->max_send_size;
int r;
assert(card != NULL && card->ops != NULL && buf != NULL);

View File

@ -33,35 +33,17 @@
static void fixup_transceive_length(const struct sc_card *card,
struct sc_apdu *apdu)
{
size_t max_send_size;
size_t max_recv_size;
assert(card != NULL && apdu != NULL);
max_send_size = card->max_send_size;
max_recv_size = card->max_recv_size;
if (card->caps & SC_CARD_CAP_APDU_EXT) {
if (!max_send_size)
max_send_size = 65535;
if (!max_recv_size)
max_recv_size = 65536;
} else {
if (!max_send_size)
max_send_size = 255;
if (!max_recv_size)
max_recv_size = 256;
}
if (apdu->lc > max_send_size) {
if (apdu->lc > card->max_send_size) {
/* The lower layers will automatically do chaining */
apdu->flags |= SC_APDU_FLAGS_CHAINING;
}
if (apdu->le > max_recv_size) {
if (apdu->le > card->max_recv_size) {
/* The lower layers will automatically do a GET RESPONSE, if possible.
* All other workarounds must be carried out by the upper layers. */
apdu->le = max_recv_size;
apdu->le = card->max_recv_size;
}
}
@ -544,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 > 0 && card->max_recv_size < 256 ? card->max_recv_size : 256;
apdu.le = card->max_recv_size < 256 ? card->max_recv_size : 256;
}
else {
apdu.p2 = 0x0C; /* first record, return nothing */
@ -737,7 +719,7 @@ iso7816_get_response(struct sc_card *card, size_t *count, u8 *buf)
size_t rlen;
/* request at most max_recv_size bytes */
if (card->max_recv_size > 0 && *count > card->max_recv_size)
if (*count > card->max_recv_size)
rlen = card->max_recv_size;
else
rlen = *count;