Hello everyone,

Here are the patches to use 2048 bit keys and the random number generator in OpenSC with the Muscle Card Applet. Only the Aladdin eToken 72K Java was tested, but it should work with any Java Card running the Muscle Applet (that supports 2048 bit keys).

There are two patches:

Muscle Card Applet (trunk) (musclecard.diff)
--------------------------------------------

* Support for extended APDUs in the ComputeCrypt() method. Encryption, decryption, etc., can work with 2048 bit keys without needing to use multiple APDUs. This patch is optional since the smart card and reader need to support extended APDUs (as is the case with the Aladdin eToken 72K).


OpenSC (0.11.7) (opensc.diff)
-----------------------------

* Small fix in msc_get_challenge(): the existing code was using the 0x72 instruction to call the GetChallenge() method, but, at least according to the latest version in the MUSCLE repository, the correct instruction number is 0x62. Also, msc_get_challenge() was returning dataLength when it should be returning 0 to indicate success;

* Make some buffers larger to support extended APDUs. The change was only from 256 to 512 bytes since it is more than enough for 2048 bit keys;

* Card detection in card-muscle.c to detect whether to activate extended APDUs or not;

* Remove the 258 byte response limit in card-pcsc.c - any help in how to correctly solve this issue is greatly appreciated;

* Do not use msc_crypt_process (OP_PROCESS). This operation is used to do multipart encryption when, for example, the data is too big to fit in one APDU. It basically calls the Cipher.update() method until all data has been processed. However, the Java Card API documentation advises against using update():

"This method requires temporary storage of intermediate results. In addition, if the input data length is not block aligned (multiple of block size) then additional internal storage may be allocated at this time to store a partial input data block. This may result in additional resource consumption and/or slow performance. This method should only be used if all the input data required for the cipher is not available in one byte array. If all the input data required for the cipher is located in a single byte array, use of the doFinal() method to process all of the input data is recommended."

As the card's JVM was returning an internal exception when using OP_PROCESS, it was decided to implement an msc_crypt_final_object() function in OpenSC that uses the msc_object_*() functions to read/write all the data from the card. This way, it is possible to transmit/receive "arbitrarily" large data chunks to/from the card and use doFinal(). This is the fallback method when, for example, using 2048 bit keys and the card doesn't support extended APDUs.

When I have some time, I plan to update the OpenSC wiki with the instructions on how to get the Aladdin eToken 72K working.

Best regards,
Joao

--
João Poupino - joao.poup...@data.identity.pt
Data Identity - IT Services
Taguspark, Núcleo Central, nº 208
2744-005 Porto Salvo
Portugal
diff -urN MCardApplet.orig/common.xml MCardApplet/common.xml
--- MCardApplet.orig/common.xml 2009-03-12 17:17:38.000000000 +0000
+++ MCardApplet/common.xml      2009-03-12 17:38:22.000000000 +0000
@@ -22,7 +22,8 @@
        <!-- The package name -->
     <property name="PACKAGE_NAME" value="${JAVA_PACKAGE}"/>
        <!--The AID of the package -->
-       <property name="PACKAGE_AID" value="0xA0:00:00:03:0x23:01"/>
+       <!-- <property name="PACKAGE_AID" value="0xA0:00:00:03:0x23:01"/> -->
+       <property name="PACKAGE_AID" value="0xA0:00:00:00:01"/>
        <!-- The major and minor version of the package -->
        <property name="VERSION" 
value="${APPLET_VERSION_MAJOR}.${APPLET_VERSION_MINOR}"/>
        <!-- The applet AID of the applet -->
@@ -206,4 +207,4 @@
            </delete>
        </target>
        
-</project>
\ No newline at end of file
+</project>
diff -urN MCardApplet.orig/CustomCapabilities.properties 
MCardApplet/CustomCapabilities.properties
--- MCardApplet.orig/CustomCapabilities.properties      2009-03-12 
17:17:38.000000000 +0000
+++ MCardApplet/CustomCapabilities.properties   2009-03-16 13:23:40.000000000 
+0000
@@ -8,7 +8,7 @@
 # -DWITH_SERIAL -DWRITE_LABEL_ONCE \
 # -DWITH_SET_STATE -DWITH_DELETE_ID -DWITH_MOVE_KEY -DWITH_MOVE_OBJECT \
 # -DWITH_CHANGE_ACL -DWITH_DELETE_KEY -DWITH_GET_CHALLENGE
-FEATURES = -DWITH_DSA -DWITH_RSA -DWITH_DES -DWITH_3DES -DWITH_SIGN 
-DWITH_ENCRYPT -DWITH_PIN_POLICY -DWITH_KEY_POLICY -DWITH_AES -DWITH_JC22 
-DWITH_EXT_AUTH -DWITH_SET_STATE -DWITH_DELETE_ID -DWITH_MOVE_KEY 
-DWITH_MOVE_OBJECT -DWITH_CHANGE_ACL -DWITH_DELETE_KEY -DWITH_GET_CHALLENGE 
-DWITH_SERIAL
+FEATURES = -DWITH_RSA -DWITH_DES -DWITH_ENCRYPT -DWITH_SIGN -DWITH_KEY_POLICY 
-DWITH_AES -DWITH_JC22 -DWITH_GARBAGE_COLLECTION -DWITH_SET_STATE 
-DWITH_DELETE_ID -DWITH_MOVE_KEY -DWITH_MOVE_OBJECT -DWITH_CHANGE_ACL 
-DWITH_DELETE_KEY -DWITH_GET_CHALLENGE -DWITH_EXT_APDU
 
 # We must enable selectively enable supported key lengths, cipher and 
signatures algorithms
 
@@ -20,7 +20,7 @@
 
 # DSA
 # -DWITH_DSA_512 -DWITH_DSA_768 -DWITH_DSA_1024
-DSAKEYLENGTHS = -DWITH_DSA_1024
+DSAKEYLENGTHS =
 
 # AES
 # -DWITH_AES_128 -DWITH_AES_192 -DWITH_AES_256
@@ -70,4 +70,4 @@
 # -DWITH_AES_MAC_128_NOPAD
 AESSIGNATUREALGORITHMS = -DWITH_AES_MAC_128_NOPAD
 
-CPPFLAGS = ${FEATURES} ${RSAKEYLENGTHS} ${AESKEYLENGTHS} ${DSAKEYLENGTHS} 
${RSACIPHERALGORITHMS} ${DESCIPHERALGORITHMS} ${AESCIPHERALGORITHMS} 
${DSASIGNATUREALGORITHMS} ${RSASIGNATUREALGORITHMS}  ${DESSIGNATUREALGORITHMS} 
${AESSIGNATUREALGORITHMS}
\ No newline at end of file
+CPPFLAGS = ${FEATURES} ${RSAKEYLENGTHS} ${AESKEYLENGTHS} ${DSAKEYLENGTHS} 
${RSACIPHERALGORITHMS} ${DESCIPHERALGORITHMS} ${AESCIPHERALGORITHMS} 
${DSASIGNATUREALGORITHMS} ${RSASIGNATUREALGORITHMS}  ${DESSIGNATUREALGORITHMS} 
${AESSIGNATUREALGORITHMS}
diff -urN MCardApplet.orig/Custom.properties MCardApplet/Custom.properties
--- MCardApplet.orig/Custom.properties  2009-03-12 17:17:38.000000000 +0000
+++ MCardApplet/Custom.properties       2009-03-12 17:30:41.000000000 +0000
@@ -1,5 +1,5 @@
-JAVA_BUILD_HOME=${basedir}/depends/jdk1.3.0_05
-JC_HOME=${basedir}/depends/jc22
+JAVA_BUILD_HOME=${basedir}/depends/jdk1.5.0_17
+JC_HOME=${basedir}/depends/jc222
 CARD_NAME=Custom
 API_JAR=${JC_HOME}/lib/api.jar
 API_EXPORT_FILES=${JC_HOME}/api_export_files
diff -urN MCardApplet.orig/src/com/musclecard/CardEdge/CardEdge.src 
MCardApplet/src/com/musclecard/CardEdge/CardEdge.src
--- MCardApplet.orig/src/com/musclecard/CardEdge/CardEdge.src   2009-03-12 
17:17:38.000000000 +0000
+++ MCardApplet/src/com/musclecard/CardEdge/CardEdge.src        2009-03-13 
10:16:57.000000000 +0000
@@ -17,6 +17,9 @@
 import javacard.framework.*;
 import javacard.security.*;
 import javacardx.crypto.*;
+#ifdef WITH_EXT_APDU
+import javacardx.apdu.ExtendedLength;
+#endif
 
 /**
  * Implements MUSCLE's Card Edge Specification.<p>
@@ -40,6 +43,8 @@
  *             WITH_EXT_AUTH
  *        <li> Enable/Disable PIN Policy enforcement:
  *             WITH_PIN_POLICY
+ *        <li> Enable/Disable Extended APDU support:
+ *             WITH_EXT_APDU
  *      </ul>
  * <li> C preprocessor defines<ul>
  *        <li> JAVA_PACKAGE:   The name of Java package for this Applet
@@ -48,7 +53,11 @@
  * </ul>
  */
 
+#ifdef WITH_EXT_APDU
+public class JAVA_APPLET extends javacard.framework.Applet implements 
ExtendedLength {
+#else
 public class JAVA_APPLET extends javacard.framework.Applet {
+#endif
 
     /* constants declaration */
 
@@ -61,6 +70,10 @@
     private final static byte MAX_NUM_AUTH_KEYS = (byte) 6;
 
 
+#ifdef WITH_EXT_APDU
+    // Maximum size for the extended APDU buffer
+    private final static short EXT_APDU_BUFFER_SIZE = (short) 512;
+#endif
     /* Pin policies constants (OR-ed in var pinPolicies) */
     /** Enable pin size check          */
     private final static byte PIN_POLICY_SIZE          = (byte) 0x01;
@@ -314,6 +327,9 @@
     // OwnerPIN objects, allocated on demand
     private OwnerPIN[] pins, ublk_pins;
 
+    // Buffer for storing extended APDUs
+    private byte[] recvBuffer;   
+
     /* Logged identities: this is used for faster access       *
      * control, so we don't have to ping each PIN object       */
     private short logged_ids;
@@ -589,22 +605,47 @@
        STD_PUBLIC_ACL = new byte[KEY_ACL_SIZE];
        for (byte i = (byte) 0; i < (byte) KEY_ACL_SIZE; i += (short) 2)
            Util.setShort(STD_PUBLIC_ACL, i, (short)0x0000);
+#ifdef WITH_EXT_APDU
+       // Initialize the extended APDU buffer
+       recvBuffer = new byte[EXT_APDU_BUFFER_SIZE];    
+#endif
 
        setupDone = true;
     }
 
     /********** UTILITY FUNCTIONS **********/
 
-    /* SendData() wraps the setGoing(), setLength(), .. stuff
-     *   that could be necessary to be fully JavaCard compliant
-     *   (the setOutgoingAndSend() could not work with all cards ?!?)  */
+    /* SendData() wraps the setGoing(), setLength(), .. stuff          *
+     *   that could be necessary to be fully JavaCard compliant.       */
     private void sendData(APDU apdu, byte[] data, short offset, short size) {
+#ifdef WITH_EXT_APDU
+       if (size > EXT_APDU_BUFFER_SIZE)
+#else
        if (size > 255)
+#endif
            ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
-       Util.arrayCopyNonAtomic(data, offset, apdu.getBuffer(), (short) 0, 
size);
-       apdu.setOutgoingAndSend((short) 0, size);
+       apdu.setOutgoing();
+       apdu.setOutgoingLength(size);
+       apdu.sendBytesLong(data, offset, size);         
+    }
+
+#ifdef WITH_EXT_APDU
+    /* Retrieves the full contents from the apdu object in case of     */
+    /*    an extended APDU.                                            */
+    private void getData(APDU apdu, byte[] src, short bytesRead, byte[] dst) {
+       short recvLen = 0;
+       short apduOffset = bytesRead;
+
+       Util.arrayCopyNonAtomic(src, (short) 0, dst, (short) 0, apduOffset);
+       do {
+               recvLen = apdu.receiveBytes((short) 0);
+               Util.arrayCopyNonAtomic(src, (short) 0, dst, apduOffset, 
recvLen);
+               apduOffset += recvLen;          
+       } while(recvLen > 0);   
+       
     }
 
+#endif
     /* Retrieves the Cipher object to be used w/ the specified key     *
      *   and algorithm id (Cipher.ALG_XX).                             *
      *   If exists, check it has the proper algorithm and throws       *
@@ -866,11 +907,29 @@
      *            APDU handlers             *
      ****************************************/
 
-    private void ComputeCrypt(APDU apdu, byte[] buffer) {
+    private void ComputeCrypt(APDU apdu, byte[] apduBuffer) {
+       /* Buffer pointer */
+       byte[] buffer = apduBuffer;
+       short dataOffset = apdu.getOffsetCdata();
+#ifdef WITH_EXT_APDU   
+       short LC = apdu.getIncomingLength();
+       short bytesLeft = apdu.setIncomingAndReceive(); 
+
+       if((short) (LC + dataOffset) > EXT_APDU_BUFFER_SIZE)
+               ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
+       
+       /* Is this an extended APDU? */
+       if(bytesLeft != LC) { 
+               getData(apdu, apduBuffer, (short) (dataOffset + bytesLeft), 
recvBuffer);
+               buffer = recvBuffer;
+               bytesLeft = LC;
+       }
+#else
        short bytesLeft = Util.makeShort((byte) 0x00,
                            buffer[ISO7816.OFFSET_LC]);
        if (bytesLeft != apdu.setIncomingAndReceive())
            ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
+#endif 
 
        byte key_nb = buffer[ISO7816.OFFSET_P1];
 
@@ -895,14 +954,14 @@
        case OP_INIT:
            if (bytesLeft < 3)
                ISOException.throwIt(SW_INVALID_PARAMETER);
-           byte ciph_mode = buffer[ISO7816.OFFSET_CDATA];
-           ciph_dir = buffer[(short) (ISO7816.OFFSET_CDATA + 1)];
+           byte ciph_mode = buffer[dataOffset];
+           ciph_dir = buffer[(short) (dataOffset + 1)];
            byte ciph_alg_id;
-           data_location = buffer[(short) (ISO7816.OFFSET_CDATA + 2)];
+           data_location = buffer[(short) (dataOffset + 2)];
            switch (data_location) {
            case DL_APDU:
                src_buff = buffer;
-               src_base = (short) (ISO7816.OFFSET_CDATA + 3);
+               src_base = (short) (dataOffset + 3);
                src_avail = (short) (bytesLeft - 3);
                break;
            case DL_OBJECT:
@@ -1025,13 +1084,13 @@
                    /* Don't know what is incorrect: just say incorrect 
parameters
                     *  we guess it was specified a wrong key number */
                    ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
-               data_location = buffer[ISO7816.OFFSET_CDATA];
+               data_location = buffer[dataOffset];
 
                switch (data_location) {
                case DL_APDU:
                    src_buff = mem.getBuffer();
                    // Skip Data Location byte.
-                   src_base = (short) (ISO7816.OFFSET_CDATA + 1);
+                   src_base = (short) (dataOffset + 1);
                    src_avail = (short) (bytesLeft - 1);
                    break;
                case DL_OBJECT:
@@ -1100,11 +1159,11 @@
                    /* Don't know what is incorrect: just say incorrect 
parameters
                     *  we guess it was specified a wrong key number */
                    ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
-               data_location = buffer[ISO7816.OFFSET_CDATA];
+               data_location = buffer[dataOffset];
                switch (data_location) {
                case DL_APDU:
                    src_buff = buffer;
-                   src_base = (short) (ISO7816.OFFSET_CDATA + 1);
+                   src_base = (short) (dataOffset + 1);
                    src_avail = (short) (bytesLeft - 1);
                    break;
                case DL_OBJECT:
diff -urN opensc-0.11.7.orig/src/libopensc/card-muscle.c 
opensc-0.11.7/src/libopensc/card-muscle.c
--- opensc-0.11.7.orig/src/libopensc/card-muscle.c      2009-03-12 
18:00:16.000000000 +0000
+++ opensc-0.11.7/src/libopensc/card-muscle.c   2009-03-12 18:00:30.000000000 
+0000
@@ -36,6 +36,12 @@
        NULL, 0, NULL
 };
 
+static struct sc_atr_table muscle_atrs[] = {
+        /* Aladdin eToken PRO USB 72K Java */
+        { "3b:d5:18:00:81:31:3a:7d:80:73:c8:21:10:30", NULL, NULL, 
SC_CARD_TYPE_MUSCLE_ETOKEN_72K, 0, NULL },
+        { NULL, NULL, NULL, 0, 0, NULL }
+};
+
 #define MUSCLE_DATA(card) ( (muscle_private_t*)card->drv_data )
 #define MUSCLE_FS(card) ( ((muscle_private_t*)card->drv_data)->fs )
 typedef struct muscle_private {
@@ -465,6 +471,14 @@
        card->flags |= SC_CARD_FLAG_ONBOARD_KEY_GEN;
        card->flags |= SC_CARD_FLAG_RNG;
        card->caps |= SC_CARD_CAP_RNG;
+
+       /* Card type detection */
+       _sc_match_atr(card, muscle_atrs, &card->type);
+       if(card->type == SC_CARD_TYPE_MUSCLE_ETOKEN_72K) {
+               card->caps |= SC_CARD_CAP_RSA_2048;
+               card->caps |= SC_CARD_CAP_APDU_EXT;
+       }
+
                /* FIXME: Card type detection */
        if (1) {
                unsigned long flags;
diff -urN opensc-0.11.7.orig/src/libopensc/cards.h 
opensc-0.11.7/src/libopensc/cards.h
--- opensc-0.11.7.orig/src/libopensc/cards.h    2009-03-12 18:00:16.000000000 
+0000
+++ opensc-0.11.7/src/libopensc/cards.h 2009-03-12 18:00:30.000000000 +0000
@@ -126,6 +126,7 @@
        /* Muscle cards */
        SC_CARD_TYPE_MUSCLE_BASE = 15000,
        SC_CARD_TYPE_MUSCLE_GENERIC,
+       SC_CARD_TYPE_MUSCLE_ETOKEN_72K,
 
        /* ACOS5 driver */
        SC_CARD_TYPE_ACOS5_BASE = 16000,
diff -urN opensc-0.11.7.orig/src/libopensc/muscle.c 
opensc-0.11.7/src/libopensc/muscle.c
--- opensc-0.11.7.orig/src/libopensc/muscle.c   2009-03-12 18:00:16.000000000 
+0000
+++ opensc-0.11.7/src/libopensc/muscle.c        2009-03-15 12:05:46.000000000 
+0000
@@ -450,7 +450,7 @@
        if(seedLength > 0) {
                memcpy(ptr, seedData, seedLength);
        }
-       sc_format_apdu(card, &apdu, cse, 0x72, 0x00, location);
+       sc_format_apdu(card, &apdu, cse, 0x62, 0x00, location);
        apdu.data = buffer;
        apdu.datalen = len;
        apdu.lc = len;
@@ -471,7 +471,7 @@
        SC_TEST_RET(card->ctx, r, "APDU transmit failed");
        if(location == 1) {
                if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
-                       return dataLength;
+                       return 0;
                } else {
                        r = sc_check_sw(card, apdu.sw1, apdu.sw2);
                        if (r) {
@@ -692,6 +692,7 @@
        SC_FUNC_RETURN(card->ctx, 0, SC_ERROR_CARD_CMD_FAILED);
 }
 
+#if 0
 int msc_compute_crypt_process(
                        sc_card_t *card, 
                        int keyLocation,
@@ -746,6 +747,7 @@
        }
        SC_FUNC_RETURN(card->ctx, 0, SC_ERROR_CARD_CMD_FAILED);
 }
+#endif
 
 int msc_compute_crypt_final(
                        sc_card_t *card, 
@@ -761,7 +763,7 @@
        u8 *ptr;
        int r;
 
-       sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x36, keyLocation, 
0x03); /* Final */
+       sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x36, keyLocation, 0x03); 
/* Final */
        
        apdu.data = buffer;
        apdu.datalen = dataLength + 3;
@@ -769,7 +771,7 @@
        
        memset(outputBuffer, 0, sizeof(outputBuffer));
        apdu.resp = outputBuffer;
-       apdu.resplen = MSC_MAX_READ;
+       apdu.resplen = dataLength + 2;
        apdu.le = dataLength +2;
        ptr = buffer;
        *ptr = 0x01; ptr++; /* DATA LOCATION: APDU */
@@ -797,6 +799,79 @@
        SC_FUNC_RETURN(card->ctx, 0, SC_ERROR_CARD_CMD_FAILED);
 }
 
+/* Stream data to the card through file IO */
+int msc_compute_crypt_final_object(
+                       sc_card_t *card, 
+                       int keyLocation,
+                       const u8* inputData,
+                       u8* outputData,
+                       size_t dataLength,
+                       size_t* outputDataLength)
+{
+       sc_apdu_t apdu;
+       u8 buffer[MSC_MAX_APDU];
+       u8 *ptr;
+       int r;
+
+       sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x36, keyLocation, 
0x03); /* Final */
+       
+       apdu.data = buffer;
+       apdu.datalen = 1;
+       apdu.lc = 1;
+       
+       ptr = buffer;
+       *ptr = 0x02; ptr++; /* DATA LOCATION: OBJECT */
+       *ptr = (dataLength >> 8) & 0xFF; ptr++;
+       *ptr = dataLength & 0xFF; ptr++;
+       memcpy(ptr, inputData, dataLength);
+
+       sc_ctx_suppress_errors_on(card->ctx);
+       r = msc_create_object(card, outputId, dataLength + 2, 0x02, 0x02, 0x02);
+       if(r < 0) { 
+               if(r == SC_ERROR_FILE_ALREADY_EXISTS) {
+                       r = msc_delete_object(card, outputId, 0);
+                       if(r < 0) {
+                               sc_ctx_suppress_errors_off(card->ctx);
+                               SC_FUNC_RETURN(card->ctx, 2, r);
+                       }
+                       r = msc_create_object(card, outputId, dataLength + 2, 
0x02, 0x02, 0x02);
+                       if(r < 0) {
+                               sc_ctx_suppress_errors_off(card->ctx);
+                               SC_FUNC_RETURN(card->ctx, 2, r);
+                       }
+               }
+       }
+       sc_ctx_suppress_errors_off(card->ctx);
+
+       r = msc_update_object(card, outputId, 0, buffer + 1, dataLength + 2);
+       if(r < 0) return r; 
+       
+       r = sc_transmit_apdu(card, &apdu);
+       SC_TEST_RET(card->ctx, r, "APDU transmit failed");
+       if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
+               r = msc_read_object(card, inputId, 2, outputData, dataLength);
+               *outputDataLength = dataLength;
+               msc_delete_object(card, outputId, 0);
+               msc_delete_object(card, inputId, 0);
+               return 0;
+       }
+       r = sc_check_sw(card, apdu.sw1, apdu.sw2);
+       if (r) {
+               if (card->ctx->debug >= 2) {
+                       sc_debug(card->ctx, "final: got strange SWs: 0x%02X 
0x%02X\n",
+                            apdu.sw1, apdu.sw2);
+               }
+       } else {
+               r = SC_ERROR_CARD_CMD_FAILED;
+       }
+       /* no error checks.. this is last ditch cleanup */      
+       sc_ctx_suppress_errors_on(card->ctx);
+       msc_delete_object(card, outputId, 0);
+       sc_ctx_suppress_errors_off(card->ctx);
+       
+       SC_FUNC_RETURN(card->ctx, 0, r);
+}
+
 int msc_compute_crypt(sc_card_t *card, 
                        int keyLocation,
                        int cipherMode,
@@ -829,30 +904,31 @@
        left -= toSend;
        inPtr += toSend;
        outPtr += received;
-       while(left > (MSC_MAX_SEND - 5)) {
-               toSend = MIN(left, (MSC_MAX_SEND - 5));
-               r = msc_compute_crypt_process(card,
+
+       toSend = MIN(left, MSC_MAX_APDU - 5);
+       /* If the card supports extended APDUs, or the data fits in
+           one normal APDU, use it for the data exchange */
+       if (left < (MSC_MAX_SEND - 4) || (card->caps & SC_CARD_CAP_APDU_EXT) != 
0) {
+               r = msc_compute_crypt_final(card,
                        keyLocation,
                        inPtr,
                        outPtr,
                        toSend,
                        &received);
                if(r < 0) SC_FUNC_RETURN(card->ctx, 0, r);
-               left -= toSend;
-               inPtr += toSend;
-               outPtr += received;
-       }
-       toSend = MIN(left, (MSC_MAX_SEND - 5));
-       r = msc_compute_crypt_final(card,
-               keyLocation,
-               inPtr,
-               outPtr,
-               toSend,
-               &received);
-       if(r < 0) SC_FUNC_RETURN(card->ctx, 0, r);
+       } else { /* Data is too big: use objects */
+               r = msc_compute_crypt_final_object(card,
+                       keyLocation,
+                       inPtr,
+                       outPtr,
+                       toSend,
+                       &received);
+               if(r < 0) SC_FUNC_RETURN(card->ctx, 0, r);
+       }       
        left -= toSend;
        inPtr += toSend;
        outPtr += received;
+       
        return outPtr - outputData; /* Amt received */
 }
 
diff -urN opensc-0.11.7.orig/src/libopensc/muscle.h 
opensc-0.11.7/src/libopensc/muscle.h
--- opensc-0.11.7.orig/src/libopensc/muscle.h   2009-03-12 18:00:16.000000000 
+0000
+++ opensc-0.11.7/src/libopensc/muscle.h        2009-03-14 00:58:07.000000000 
+0000
@@ -28,7 +28,7 @@
 
 #include "muscle-filesystem.h"
 
-#define MSC_MAX_APDU 256 /* Max APDU send/recv, used for stack allocation */
+#define MSC_MAX_APDU 512 /* Max APDU send/recv, used for stack allocation */
 #define MSC_MAX_PIN_LENGTH 8
 #define MSC_MAX_PIN_COMMAND_LENGTH ((1 + MSC_MAX_PIN_LENGTH) * 2)
 
diff -urN opensc-0.11.7.orig/src/libopensc/reader-pcsc.c 
opensc-0.11.7/src/libopensc/reader-pcsc.c
--- opensc-0.11.7.orig/src/libopensc/reader-pcsc.c      2009-03-12 
18:00:16.000000000 +0000
+++ opensc-0.11.7/src/libopensc/reader-pcsc.c   2009-03-14 15:37:52.000000000 
+0000
@@ -169,9 +169,12 @@
 
        dwSendLength = sendsize;
        dwRecvLength = *recvsize;
-
+       
+       /* FIXME: Extended APDUs need support for LE > 258 */
+       /*
        if (dwRecvLength > 258)
                dwRecvLength = 258;
+       */
 
        if (!control) {
                rv = priv->gpriv->SCardTransmit(card, &sSendPci, sendbuf, 
dwSendLength,
$ pkcs11-tool --login --test
Please enter User PIN: 
C_SeedRandom() and C_GenerateRandom():
  seeding (C_SeedRandom) not supported
  seems to be OK
Digests:
  all 4 digest functions seem to work
  MD5: OK
  SHA-1: OK
  RIPEMD160: OK
Signatures (currently only RSA signatures)
  testing key 0 (Private Key) 
  all 4 signature functions seem to work
  testing signature mechanisms:
    RSA-X-509: OK
    RSA-PKCS: OK
    SHA1-RSA-PKCS: OK
    MD5-RSA-PKCS: OK
    RIPEMD160-RSA-PKCS: OK
  testing key 1 (2048 bits, label=Private Key) with 1 signature mechanism
    MD5-RSA-PKCS: OK
Verify (currently only for RSA):
  testing key 0 (Private Key)
    RSA-X-509: OK
    RSA-PKCS: OK
    SHA1-RSA-PKCS: OK
    MD5-RSA-PKCS: OK
    RIPEMD160-RSA-PKCS: OK
  testing key 1 (Private Key) with 1 mechanism
    RSA-X-509: OK
Key unwrap (RSA)
  testing key 0 (Private Key) 
    DES-CBC: OK
    DES-EDE3-CBC: OK
    BF-CBC: OK
    CAST5-CFB: OK
  testing key 1 (Private Key) 
    DES-CBC: OK
    DES-EDE3-CBC: OK
    BF-CBC: OK
    CAST5-CFB: OK
Decryption (RSA)
  testing key 0 (Private Key) 
    RSA-X-509: OK
    RSA-PKCS: OK
  testing key 1 (Private Key) 
    RSA-X-509: OK
    RSA-PKCS: OK
Testing card detection
Please press return to continue, x to exit: x
Testing card detection using C_WaitForSlotEvent
Please press return to continue, x to exit: x
No errors
_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to