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?

see comments below

Log Message:
-----------
only the first apdu (command) tells us how many bytes we need to get.
we need to keep this value and call get_response as often as needed
to get them part by part.

Modified Paths:
--------------
    trunk/src/libopensc/apdu.c
Modified: trunk/src/libopensc/apdu.c
===================================================================
--- trunk/src/libopensc/apdu.c  2006-12-22 12:43:00 UTC (rev 3092)
+++ trunk/src/libopensc/apdu.c  2006-12-29 09:44:13 UTC (rev 3093)
@@ -448,6 +448,7 @@
                         */
                        size_t le, buflen;
                        u8     *buf;
+                       int     len = apdu->sw2 != 0 ? (size_t)apdu->sw2 : 256;

the size_t cast looks strange here as len is an int (why int ?), but that's
not really important

if (card->ops->get_response == NULL) {
                                /* this should _never_ happen */
@@ -466,13 +467,13 @@
                        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);
                                r = card->ops->get_response(card, &le, tbuf);
                                if (r < 0)
                                        SC_FUNC_RETURN(ctx, 2, r);
@@ -483,7 +484,7 @@
                                memcpy(buf, tbuf, le);
                                buf    += le;
                                buflen -= le;

btw: I guess something like
                                le = (size_t)r;
was missing here.

-                       } while (r != 0);
+                       } while (r != 0 || (buf - apdu->resp < len));
                        /* we've read all data, let's return 0x9000 */
                        apdu->resplen = buf - apdu->resp;
                        apdu->sw1 = 0x90;

the reason why I implemented it the way it was before is that,
as far as I remember, some cards use the trick to return 0x6100
several times to return more than 256 bytes without using extended
APDUs (this is for example necessary if you want to return more
than 256 bytes in a GET DATA call). With your patch at most 256
bytes are returned ...
None of the cards I currently use need this feature but I do not
really agree that only the first bytes tells us the total amount of
bytes to read. IMHO 0x61xx just tells us that *at least* xx bytes
are left to be read (and not *at most*).

When I wrote this code I wasn't aware of the 'strange' behaviour
of cryptoflex cards ... I need to think about it.

Cheers,
Nils
_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to