Failed to send Extended APDU

折月煮酒 提交于 2019-11-27 19:04:38

问题


I have a big byte array (it's 320 bytes) on my Java Card and I want to send its data in one APDU response.

So, I implemented ExtendedLength interface in my applet and then used the following program:

package exPack;

import javacard.framework.*;
import javacardx.apdu.ExtendedLength;

public class testExtended extends Applet implements ExtendedLength {

    byte[] longData = {(byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09};

    public static void install(byte[] bArray, short bOffset, byte bLength) {
        new testExtended();
    }

    protected testExtended() {
        register();
    }

    public void process(APDU apdu) {
        if (selectingApplet()) {
            ISOException.throwIt((short) 0x9001);
        }
        byte[] buffer = apdu.getBuffer();
        short toSend = (short) longData.length;
        byte counter = 0;
        while (toSend > 0) {
            Util.arrayCopyNonAtomic(longData, (short) (counter * 32), buffer, (short) 0, (short) 32);
            apdu.sendBytes((short) 0, (short) 32);
            toSend = (short) (toSend - 32);
            counter = (byte) (counter + 1);
        }
    }
}

The problem is that in the line apdu.sendBytes((short) 0, (short) 32); I I receive a 0x6F00 error. I found the point of error using throwing an exception before and then after this line.

This is the response of above program:

Download Cap begin...
Download Cap successful.
Install Applet begin...
Install Applet successful.
Send: 00 A4 04 00 06 11 22 33 44 55 11 00
Recv: 90 01
Time used: 15.000 ms
Send: 00 00 00 00
Recv: 6F 00
Time used: 11.000 ms

Can anybody help me to handle it?


回答1:


I made your code work on all my cards:

import javacard.framework.*;
import javacardx.apdu.ExtendedLength;

public class MiniApplet extends Applet implements ExtendedLength {

    byte[] longData = {(byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09};

    public static void install(byte[] bArray, short bOffset, byte bLength) {
        new MiniApplet();
    }

    protected MiniApplet() {
        register();
    }

    public void process(APDU apdu) {
        if (selectingApplet()) {
            return;
        }
        short toSend = (short) longData.length;

        try {
            apdu.setOutgoing();
            apdu.setOutgoingLength(toSend);

            byte counter = 0;
            while (toSend > 0) {
                apdu.sendBytesLong(longData, (short) (32 * counter), (short) 32);
                toSend = (short) (toSend - 32);
                counter = (byte) (counter + 1);
            }
        } catch (Exception e) {
            if (e instanceof APDUException) {
                APDUException ae = (APDUException) e;
                short reason = ae.getReason();
                if (reason == APDUException.BAD_LENGTH)
                    ISOException.throwIt((short) 0x9990);
                else
                    ISOException.throwIt((short) 0x8887);
            } else {
                ISOException.throwIt((short) 0x8888);
            }
        }
    }
}

APDU log:

=> 00 A4 04 00 08 F0 6D 69 6E 69 61 70 70 00  //different AID, not important
<= 90 00 //I got rid of your 9001, because it made my simulator mad

=> 00 00 00 00  //standard format                                       
<= 99 90 //APDUException.BAD_LENGTH thrown by apdu.setOutgoingLength(>256)

=> 00 00 00 00 00 00 00 //extended APDU format
<= 00 10 ... all your data, 320 bytes ... 90 00

If this code does not work on your cards, it will be probably a bug in your javacardx package implementation and you should contact the vendor.




回答2:


An unhandled exception was thrown by your applet because you called sendBytes() without calling setOutgoing() and setOutgoingLength() first.

Also, I haven't really counted the length of longData but make sure that its length is a multiple of 32 bytes otherwise Util.arrayCopyNonAtomic() will throw an ArrayIndexOutOfBoundsException and will make your applet throw 6F00.

Maybe you can try it this way:

    apdu.setOutgoing();
    apdu.setOutgoingLength(toSend);
    while (toSend > 0) {
        Util.arrayCopyNonAtomic(longData, (short) (counter * 32), buffer, (short) 0, (short) 32);
        apdu.sendBytes((short) 0, (short) 32);
        toSend = (short) (toSend - 32);
        counter = (byte) (counter + 1);
    }

Or much better, instead of doing a while loop:

    apdu.setOutgoing();
    apdu.setOutgoingLength(toSend);
    apdu.sendBytesLong(longData, (short)0, toSend);


来源:https://stackoverflow.com/questions/34415519/failed-to-send-extended-apdu

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!