Merge pull request #534 from frankmorgner/card-sizes
reactivate handling of `0` for max_recv/send_size
This commit is contained in:
commit
3f43bc46ef
|
@ -581,7 +581,7 @@ int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu)
|
||||||
* bytes using command chaining */
|
* bytes using command chaining */
|
||||||
size_t len = apdu->datalen;
|
size_t len = apdu->datalen;
|
||||||
const u8 *buf = apdu->data;
|
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) {
|
while (len != 0) {
|
||||||
size_t plen;
|
size_t plen;
|
||||||
|
|
|
@ -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.lc = pathlen;
|
||||||
apdu.data = path;
|
apdu.data = path;
|
||||||
apdu.datalen = pathlen;
|
apdu.datalen = pathlen;
|
||||||
apdu.le = card->max_recv_size;
|
apdu.le = sc_get_max_recv_size(card);
|
||||||
if (p1 == 3)
|
if (p1 == 3)
|
||||||
apdu.cse= SC_APDU_CASE_1;
|
apdu.cse= SC_APDU_CASE_1;
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,7 @@ static int sc_hsm_read_binary(sc_card_t *card,
|
||||||
cmdbuff[2] = (idx >> 8) & 0xFF;
|
cmdbuff[2] = (idx >> 8) & 0xFF;
|
||||||
cmdbuff[3] = idx & 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);
|
sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0xB1, 0x00, 0x00);
|
||||||
apdu.data = cmdbuff;
|
apdu.data = cmdbuff;
|
||||||
apdu.datalen = 4;
|
apdu.datalen = 4;
|
||||||
|
|
|
@ -135,6 +135,54 @@ static void sc_card_free(sc_card_t *card)
|
||||||
free(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)
|
int sc_connect_card(sc_reader_t *reader, sc_card_t **card_out)
|
||||||
{
|
{
|
||||||
sc_card_t *card;
|
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;
|
card->name = card->driver->name;
|
||||||
|
|
||||||
/* initialize max_send_size/max_recv_size to a meaningfull value */
|
/* initialize max_send_size/max_recv_size to a meaningfull value */
|
||||||
if (card->caps & SC_CARD_CAP_APDU_EXT) {
|
card->max_recv_size = sc_get_max_recv_size(card);
|
||||||
if (!card->max_send_size)
|
card->max_send_size = sc_get_max_send_size(card);
|
||||||
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;
|
|
||||||
|
|
||||||
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);
|
||||||
|
@ -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,
|
int sc_read_binary(sc_card_t *card, unsigned int idx,
|
||||||
unsigned char *buf, size_t count, unsigned long flags)
|
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;
|
int r;
|
||||||
|
|
||||||
assert(card != NULL && card->ops != NULL && buf != NULL);
|
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,
|
int sc_write_binary(sc_card_t *card, unsigned int idx,
|
||||||
const u8 *buf, size_t count, unsigned long flags)
|
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;
|
int r;
|
||||||
|
|
||||||
assert(card != NULL && card->ops != NULL && buf != NULL);
|
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,
|
int sc_update_binary(sc_card_t *card, unsigned int idx,
|
||||||
const u8 *buf, size_t count, unsigned long flags)
|
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;
|
int r;
|
||||||
|
|
||||||
assert(card != NULL && card->ops != NULL && buf != NULL);
|
assert(card != NULL && card->ops != NULL && buf != NULL);
|
||||||
|
|
|
@ -35,15 +35,15 @@ static void fixup_transceive_length(const struct sc_card *card,
|
||||||
{
|
{
|
||||||
assert(card != NULL && apdu != NULL);
|
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 */
|
/* The lower layers will automatically do chaining */
|
||||||
apdu->flags |= SC_APDU_FLAGS_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.
|
/* The lower layers will automatically do a GET RESPONSE, if possible.
|
||||||
* All other workarounds must be carried out by the upper layers. */
|
* 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.p2 = 0; /* first record, return FCI */
|
||||||
apdu.resp = buf;
|
apdu.resp = buf;
|
||||||
apdu.resplen = sizeof(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 {
|
else {
|
||||||
apdu.p2 = 0x0C; /* first record, return nothing */
|
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;
|
size_t rlen;
|
||||||
|
|
||||||
/* request at most max_recv_size bytes */
|
/* request at most max_recv_size bytes */
|
||||||
if (*count > card->max_recv_size)
|
if (*count > sc_get_max_recv_size(card))
|
||||||
rlen = card->max_recv_size;
|
rlen = sc_get_max_recv_size(card);
|
||||||
else
|
else
|
||||||
rlen = *count;
|
rlen = *count;
|
||||||
|
|
||||||
|
|
|
@ -910,6 +910,30 @@ int sc_lock(struct sc_card *card);
|
||||||
*/
|
*/
|
||||||
int sc_unlock(struct sc_card *card);
|
int sc_unlock(struct sc_card *card);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Calculate the maximum size of R-APDU payload (Ne).
|
||||||
|
*
|
||||||
|
* Takes card limitations into account such as extended length support as well
|
||||||
|
* as the reader's limitation for data transfer.
|
||||||
|
*
|
||||||
|
* @param card Initialized card object with its reader
|
||||||
|
*
|
||||||
|
* @return maximum Ne
|
||||||
|
*/
|
||||||
|
size_t sc_get_max_recv_size(const sc_card_t *card);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Calculate the maximum size of C-APDU payload (Nc).
|
||||||
|
*
|
||||||
|
* Takes card limitations into account such as extended length support as well
|
||||||
|
* as the reader's limitation for data transfer.
|
||||||
|
*
|
||||||
|
* @param card
|
||||||
|
*
|
||||||
|
* @return maximum Nc
|
||||||
|
*/
|
||||||
|
size_t sc_get_max_send_size(const sc_card_t *card);
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
/* ISO 7816-4 related functions */
|
/* ISO 7816-4 related functions */
|
||||||
|
|
Loading…
Reference in New Issue