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

Reply via email to