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
This commit is contained in:
aj 2010-02-05 06:14:19 +00:00
parent 85613b459d
commit 119c7751c7

View File

@ -530,10 +530,13 @@ int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu)
} }
if ((apdu->flags & SC_APDU_FLAGS_CHAINING) != 0) { 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 */ * 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 > 0) ?
card->max_send_size :
card->reader->driver->max_send_size);
while (len != 0) { while (len != 0) {
size_t plen; size_t plen;
@ -543,14 +546,14 @@ int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu)
tapdu = *apdu; tapdu = *apdu;
/* clear chaining flag */ /* clear chaining flag */
tapdu.flags &= ~SC_APDU_FLAGS_CHAINING; tapdu.flags &= ~SC_APDU_FLAGS_CHAINING;
if (len > 255) { if (len > max_send_size) {
/* adjust APDU case: in case of CASE 4 APDU /* adjust APDU case: in case of CASE 4 APDU
* the intermediate APDU are of CASE 3 */ * the intermediate APDU are of CASE 3 */
if ((tapdu.cse & SC_APDU_SHORT_MASK) == SC_APDU_CASE_4_SHORT) if ((tapdu.cse & SC_APDU_SHORT_MASK) == SC_APDU_CASE_4_SHORT)
tapdu.cse--; tapdu.cse--;
/* XXX: the chunk size must be adjusted when /* XXX: the chunk size must be adjusted when
* secure messaging is used */ * secure messaging is used */
plen = 255; plen = max_send_size;
tapdu.cla |= 0x10; tapdu.cla |= 0x10;
tapdu.le = 0; tapdu.le = 0;
/* the intermediate APDU don't expect data */ /* the intermediate APDU don't expect data */