On Fri, 2006-12-29 at 10:50 +0100, Andreas Jellinghaus wrote: > at least with cryptoflex only the sign apdu returns 0x61 and the number > of bytes we can fetch. all get response commands return 90 00. so we > need to keep the number of bytes to get from the first command, and then > loop till we received all bytes. > > I hope this also works with all other smart cards? > Nils, is this change ok for you? This change breaks PIV chaining. PIV Cards keep on returning 6100 until all of the data is read.
The length setting at the top will permit at most 256 bytes to be read from a card. Attached is a patch to the current svn (-r3097) to fix the previous patch to work with PIV. It reverts some of the changes, but sets a cap on the data received. If le is greater than the remaining buffer, it is capped at the remaining buffer before the get_response is sent. If this doesn't fix the issue... then perhaps there needs to be a card-specific get_response for that card. Another potential fix is to modify the previous patch such that if the returned data length is less than the expected data return, to read the remainder until that's done.(or maybe this belongs in the card-specific get_response or in the ISO get_response code.) After looking through things... it looks like this code does belong in the ISO get_response, since it should be expected that get_response gets _ALL_ of the response that it was expecting... though I suppose this train of thought could be placed on apdu.c as well. Putting it in ISO, however makes things a little more customizable. -- Thomas Harning Jr. Authentication Engineer @ Identity Alliance http://www.trustbearer.com/
Index: src/libopensc/apdu.c =================================================================== --- src/libopensc/apdu.c (revision 3097) +++ src/libopensc/apdu.c (working copy) @@ -448,7 +448,6 @@ */ size_t le, buflen; u8 *buf; - int len = apdu->sw2 != 0 ? (size_t)apdu->sw2 : 256; if (card->ops->get_response == NULL) { /* this should _never_ happen */ @@ -467,13 +466,16 @@ buflen = olen - apdu->resplen; /* 0x6100 means at least 256 more bytes to read */ + le = apdu->sw2 != 0 ? (size_t)apdu->sw2 : 256; do { u8 tbuf[256]; /* call GET RESPONSE to get more date from * the card; note: GET RESPONSE returns the * amount of data left (== SW2) */ - le = len - (buf - apdu->resp); + /* Cap the response request */ + if(le > buflen - (buf - apdu->resp)) + le = buflen - (buf - apdu->resp); r = card->ops->get_response(card, &le, tbuf); if (r < 0) SC_FUNC_RETURN(ctx, 2, r); @@ -484,7 +486,7 @@ memcpy(buf, tbuf, le); buf += le; buflen -= le; - } while (r != 0 || (buf - apdu->resp < len)); + } while (r != 0); /* we've read all data, let's return 0x9000 */ apdu->resplen = buf - apdu->resp; apdu->sw1 = 0x90;
_______________________________________________ opensc-devel mailing list opensc-devel@lists.opensc-project.org http://www.opensc-project.org/mailman/listinfo/opensc-devel