From c8915449903801db84c5a559ce3c731e3590515a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?= Date: Fri, 1 Jun 2012 19:57:26 +0200 Subject: [PATCH] OpenPGP: Use command chaining to send large data if extended APDU is not supported. --- src/libopensc/card-openpgp.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index febe0dac..25183880 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1046,17 +1046,24 @@ pgp_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len) } /* Build APDU */ + /* Large data can be sent via extended APDU, if card supports */ if (buf_len > 0xFF && card->caps & SC_CARD_CAP_APDU_EXT) { sc_format_apdu(card, &apdu, SC_APDU_CASE_3_EXT, 0xDA, tag >> 8, tag); } - else { - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDA, tag >> 8, tag); - /* In short APDU, the Lc only takes 1 byte */ - apdu.lc = ((buf_len > 0xFF) && !(card->caps & SC_CARD_CAP_APDU_EXT)) ? 0xFF : buf_len; + /* Card/Reader does not support extended, use command chaining, if supported */ + else if (buf_len > 0xFF && priv->ext_caps & EXT_CAP_CHAINING) { + sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xDA, tag >> 8, tag); + apdu.flags |= SC_APDU_FLAGS_CHAINING; + /* FIXME: The case of command chaining is not tested. */ } - /* TODO: - * Command chaining for the large data. - **/ + else if (buf_len <= 0xFF) { + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDA, tag >> 8, tag); + } + else { + sc_log(card->ctx, "Data is too big to send."); + return SC_ERROR_INVALID_DATA; + } + apdu.data = buf; apdu.datalen = buf_len; apdu.lc = buf_len;