Hi!

In the svn tree there is a change that breaks my code: The ISO
driver automatically sends read binary APDUs until the number of
requested bytes is reached (iso7816.c:136).
You mean r5237 [1] ?
Yes!

Previously only one APDU was sent. The change surely intendeds to
read as much as possible (and requested). The problem is that 6282
is only recognized when the card returns 0 bytes of data
(iso7816.c:132).
SW 6282 as in "End of file or record reached before reading Le
bytes"
Yes!

There are three alternatives for a fix, I think:
1. Offer a flag to disable the new behaviour as it is done for get
response with SC_APDU_FLAGS_NO_GET_RESP.
Flag for sc_read_binary I assume?
Yes!

2. Offer a possibilities to read a file to EOF.
3. Correctly recognize 6282 even when data is present.
How would the two approaches differ? 2) would return as much as
possible, ignoring such (meaningless in some context?) errors and 3)
would correctly raise the error, even if data is received?
The second solution would require a mechanism to return a buffer of data
with enough bytes allocated (so the library allocates the memory).  But
all other functions of libopensc require the caller to allocate enough
space.

In the third solution the caller still allocates memory. He then
sequentially calls sc_read_binary with more and more space allocated. He
stops when the first error is thrown.

The problem I have is to read a file with an unknown length. I
used the third solution which worked before r5237.

I think that a flag could be invented for switching between these
two modes of operation (the otherwise unused "flags" parameter to
sc_read_binary).  The default could be the mode that honors passed
in parameters.
Actually the 0x6282 is mapped to the general SC_ERROR_CARD_CMD_FAILED
error.
http://www.opensc-project.org/opensc/browser/trunk/src/libopensc/iso7816.c?rev=5237#L35

Possible resolution could be:

A new code error is introduced for the SW 0x6282 .
The 6282 error is ignored if it's returned by the 'embedded'
iso7816_read_binary .
http://www.opensc-project.org/opensc/browser/trunk/src/libopensc/iso7816.c?rev=5237#L137
Line 138 very well tests the return code. BUT sc_check_sw is not called
unless the number of bytes to be read is 0 (line 132, 133). So the
iso7816_read_binary almost never recognizes errors which are
communicated via the status bytes. So an other solution could be to
always check the status bytes (not only for apdu.resplen == 0).

You have a reason,
and I guess that 6282 SW is never returned with resplen=0.

Solution could be like in attached diff.
Sorry, I have no appropriate card to test.

But
adding an error code for these status bytes could be useful anyway.

[1]http://www.opensc-project.org/opensc/changeset/5237
Cheers, Frank.


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


--
Viktor Tarasov  <viktor.tara...@opentrust.com>

Index: src/libopensc/iso7816.c
===================================================================
--- src/libopensc/iso7816.c     (révision 5375)
+++ src/libopensc/iso7816.c     (copie de travail)
@@ -32,7 +32,7 @@
 static const struct sc_card_error iso7816_errors[] = {
        { 0x6200, SC_ERROR_MEMORY_FAILURE,      "State of non-volatile memory 
unchanged" },
        { 0x6281, SC_ERROR_MEMORY_FAILURE,      "Part of returned data may be 
corrupted" },
-       { 0x6282, SC_ERROR_CARD_CMD_FAILED,     "End of file/record reached 
before reading Le bytes" },
+       { 0x6282, SC_WARNING_FILE_END_REACHED,  "Warning: end of file/record 
reached before reading Le bytes" },
        { 0x6283, SC_ERROR_CARD_CMD_FAILED,     "Selected file invalidated" },
        { 0x6284, SC_ERROR_CARD_CMD_FAILED,     "FCI not formatted according to 
ISO 7816-4" },
 
@@ -133,6 +133,10 @@
                SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, 
sc_check_sw(card, apdu.sw1, apdu.sw2));
        memcpy(buf, recvbuf, apdu.resplen);
 
+       r =  sc_check_sw(card, apdu.sw1, apdu.sw2);
+       if (r == SC_WARNING_FILE_END_REACHED)
+               SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, apdu.resplen);
+
        if (apdu.resplen < count)   {
                r = iso7816_read_binary(card, idx + apdu.resplen, buf + 
apdu.resplen, count - apdu.resplen, flags);
                SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit 
failed");
Index: src/libopensc/errors.h
===================================================================
--- src/libopensc/errors.h      (révision 5375)
+++ src/libopensc/errors.h      (copie de travail)
@@ -106,6 +106,9 @@
 #define SC_ERROR_INVALID_PIN_REFERENCE         -1509
 #define SC_ERROR_FILE_TOO_SMALL                        -1510
 
+/* Warnings */ 
+#define SC_WARNING_FILE_END_REACHED            -1601
+
 /* Errors that do not fit the categories above */
 #define SC_ERROR_UNKNOWN                       -1900
 #define SC_ERROR_PKCS15_APP_NOT_FOUND          -1901
_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to