From 119c7751c79eba8c467ec731542e38c9ea82c7b4 Mon Sep 17 00:00:00 2001 From: aj Date: Fri, 5 Feb 2010 06:14:19 +0000 Subject: [PATCH] Improved chaining for large APDU commands, by Mats Andersson and Douglas E. Engert. git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3997 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/apdu.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libopensc/apdu.c b/src/libopensc/apdu.c index 41ea25e1..794dcc60 100644 --- a/src/libopensc/apdu.c +++ b/src/libopensc/apdu.c @@ -530,10 +530,13 @@ int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu) } if ((apdu->flags & SC_APDU_FLAGS_CHAINING) != 0) { - /* divide et impera: transmit APDU in chunks with Lc < 255 + /* divide et impera: transmit APDU in chunks with Lc <= max_send_size * 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 : + card->reader->driver->max_send_size); while (len != 0) { size_t plen; @@ -543,14 +546,14 @@ int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu) tapdu = *apdu; /* clear chaining flag */ tapdu.flags &= ~SC_APDU_FLAGS_CHAINING; - if (len > 255) { + if (len > max_send_size) { /* adjust APDU case: in case of CASE 4 APDU * the intermediate APDU are of CASE 3 */ if ((tapdu.cse & SC_APDU_SHORT_MASK) == SC_APDU_CASE_4_SHORT) tapdu.cse--; /* XXX: the chunk size must be adjusted when * secure messaging is used */ - plen = 255; + plen = max_send_size; tapdu.cla |= 0x10; tapdu.le = 0; /* the intermediate APDU don't expect data */