Skip to content

Instantly share code, notes, and snippets.

@fishsoupisgood
Created February 25, 2018 15:27
Show Gist options
  • Save fishsoupisgood/1c1b7a80ed8feb03d64ef1a57962ee76 to your computer and use it in GitHub Desktop.
Save fishsoupisgood/1c1b7a80ed8feb03d64ef1a57962ee76 to your computer and use it in GitHub Desktop.
--- opensc-0.17.1.orig/src/libopensc/apdu.c
+++ opensc-0.17.1/src/libopensc/apdu.c
@@ -424,7 +424,7 @@ sc_set_le_and_transmit(struct sc_card *c
static int
-sc_get_response(struct sc_card *card, struct sc_apdu *apdu, size_t olen)
+sc_get_response(struct sc_card *card, struct sc_apdu *apdu, size_t olen, int complete_reads)
{
struct sc_context *ctx = card->ctx;
size_t le, minlen, buflen;
@@ -497,6 +497,11 @@ sc_get_response(struct sc_card *card, st
le = minlen;
} while (rv != 0 && minlen != 0);
+ while ( complete_reads && (rv > 0)) {
+ unsigned char resp[256];
+ size_t resp_len;
+ rv=card->ops->get_response(card, &resp_len, resp);
+ }
/* we've read all data, let's return 0x9000 */
apdu->resplen = buf - apdu->resp;
apdu->sw1 = 0x90;
@@ -512,7 +517,7 @@ sc_get_response(struct sc_card *card, st
* @return SC_SUCCESS on success and an error value otherwise
*/
static int
-sc_transmit(sc_card_t *card, sc_apdu_t *apdu)
+sc_transmit(sc_card_t *card, sc_apdu_t *apdu, int complete_reads)
{
struct sc_context *ctx = card->ctx;
size_t olen = apdu->resplen;
@@ -536,8 +541,8 @@ sc_transmit(sc_card_t *card, sc_apdu_t *
* Unless the SC_APDU_FLAGS_NO_GET_RESP is set we try to read as
* much data as possible using GET RESPONSE.
*/
- if (apdu->sw1 == 0x61 && (apdu->flags & SC_APDU_FLAGS_NO_GET_RESP) == 0)
- r = sc_get_response(card, apdu, olen);
+ if (apdu->sw1 == 0x61 && (((apdu->flags & SC_APDU_FLAGS_NO_GET_RESP) == 0) || complete_reads))
+ r = sc_get_response(card, apdu, olen, complete_reads);
LOG_TEST_RET(ctx, r, "cannot get all data with 'GET RESPONSE'");
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
@@ -609,7 +614,7 @@ int sc_transmit_apdu(sc_card_t *card, sc
break;
}
- r = sc_transmit(card, &tapdu);
+ r = sc_transmit(card, &tapdu, 1);
if (r != SC_SUCCESS)
break;
if (last != 0) {
@@ -629,7 +634,7 @@ int sc_transmit_apdu(sc_card_t *card, sc
}
} else
/* transmit single APDU */
- r = sc_transmit(card, apdu);
+ r = sc_transmit(card, apdu, 0);
/* all done => release lock */
if (sc_unlock(card) != SC_SUCCESS)
sc_log(card->ctx, "sc_unlock failed");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment