1

I'm new to this field, so forgive me if my question is naive.

I want to issue a Java card which has an auto-select applet and almost all APDUs are going to get handled in this applet. I need this applet to send data to CAD not using the usual format in Java card standard (i.e. without sending 0x61 0xbytesToRead and waiting for 0x00 0xc0).
For example I'd like to send 0x23 bytes in answer to 0xA0A40000027F20 which is almost a SELECT command but with wrong first byte!

So is this possible to do this? and if it's possible please tell me how.

Thanks.

MFA
  • 537
  • 2
  • 6
  • 16

1 Answers1

4

Yes, it is possible. To aim your goal, you have two steps as below :

  1. You must make your applet default selected.
  2. You must return some data on reception of this command, and/or reception of SELECT APDU command.

For the first step, as it is answered here:

It depends on cards - not all of them seem to support making an applet default after installation. But you can use the open source GlobalPlatform tool for Java that has --make-default option:

java -jar gp.jar --make-default A000100201100001

IIRC JCOP was one of the cards that actually supported it.

And for the second step, as answered here :

I guess you do the "good practice" of "if selectingApplet() then return" in process? You need to process the incoming APDU instead of simple return. You can return data to select the normal way, but be careful to return 0x9000 if the select was successful.

It must be looked like this:

public void process(APDU apdu)
    { 
       byte[] buf = apdu.getBuffer();
       if (selectingApplet())
          { 
          //send the data in buffer return;
          }
    } 

Update:

To answer your comment below this answer :

I wrote the below program :

package test;

import javacard.framework.APDU;
import javacard.framework.ISO7816;
import javacard.framework.Applet;
import javacard.framework.ISOException;
import javacard.framework.Util;

public class Test extends Applet {

    public static final byte[] res = { (byte) 0x00, (byte) 0x00, (byte) 0x3B,
            (byte) 0xAD, (byte) 0x3F, (byte) 0x00, (byte) 0x01, (byte) 0x00,
            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x16,
            (byte) 0xB3, (byte) 0x03, (byte) 0x06, (byte) 0x04, (byte) 0x00,
            (byte) 0x83, (byte) 0x8A, (byte) 0x83, (byte) 0x8A, (byte) 0x00,
            (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x3B, (byte) 0xAD,
            (byte) 0x00, (byte) 0x00, (byte) 0x3B, (byte) 0xAD, (byte) 0x2F,
            (byte) 0x06, (byte) 0x02 };

    public static void install(byte[] bArray, short bOffset, byte bLength) {
        new test.Test()
                .register(bArray, (short) (bOffset + 1), bArray[bOffset]);
    }

    public void process(APDU apdu) {
        if (selectingApplet()) {
            return;
        }

        byte[] buf = apdu.getBuffer();

        if (buf[ISO7816.OFFSET_CLA] == (byte)0xA0 && buf[ISO7816.OFFSET_INS] == (byte) 0xA4 && buf[ISO7816.OFFSET_P1] == (byte) 0x00&& buf[ISO7816.OFFSET_P2] == (byte) 0x00 
                && buf[ISO7816.OFFSET_LC] == (byte) 0x02 && buf[ISO7816.OFFSET_LC + 1] == (byte) 0x7F  && buf[ISO7816.OFFSET_LC + 2] == (byte) 0x20) {
            ISOException.throwIt((short) 0x9F23);
        } else if (buf[ISO7816.OFFSET_CLA] == (byte) 0xA0 && buf[ISO7816.OFFSET_INS] == (byte) 0xC0  && buf[ISO7816.OFFSET_P1] == (byte) 0x00 
                && buf[ISO7816.OFFSET_P2] == (byte) 0x00  && buf[ISO7816.OFFSET_P2+1] == (byte) 0x23 ) {
            Util.arrayCopyNonAtomic(res, (short) 0, buf, (short) 0, (short) 35);
            apdu.setOutgoingAndSend((short) 0, (short) 35);

        } else {
            ISOException.throwIt((short) 0x9090);
        }
    }
}

Then I installed it as default selected applet :

CommandLine> gp -install e:\soq.cap --default

CommandLine>

And then I send the APDU commands to it :

CommandLine> OSC.exe -s A0A40000027F20 -s a0c0000023
Using reader with a card: ACS CCID USB Reader 0
Sending: A0 A4 00 00 02 7F 20
Received (SW1=0x9F, SW2=0x23)
Sending: A0 C0 00 00 23
Received (SW1=0x90, SW2=0x00):
00 00 3B AD 3F 00 01 00 00 00 00 00 16 B3 03 06 ..;.?...........
04 00 83 8A 83 8A 00 03 00 00 3B AD 00 00 3B AD ..........;...;.
2F 06 02                                        /..

It seems that it works as you wanted.

Community
  • 1
  • 1
Ebrahim Ghasemi
  • 5,850
  • 10
  • 52
  • 113
  • Dear Abraham. These are the request and responses that should happen. please see below and tell me if it's possible (and it's from SIM APDU as you've probably mentioned by now) >> in: `0xA0 A4 00 00 02 7F 20` << out: `0x9F 23` >> in : `0xA0 C0 00 00 23` << out: `0x00 00 3B AD 3F 00 01 00 00 00 00 00 16 B3 03 06 04 00 83 8A 83 8A 00 03 00 00 3B AD 00 00 3B AD 2F 06 02` – MFA Jul 15 '15 at 06:50
  • @MFA Follow [this](http://stackoverflow.com/questions/31424648/default-selected-applet-doesnt-return-right-value) question to receive your answer. – Ebrahim Ghasemi Jul 15 '15 at 07:59
  • Thanks, I really appreciate your help. – MFA Jul 15 '15 at 10:42
  • Thanks a lot, I tested it but there is a difference between what you get and what I receive. In my case, when the card received `0xa0c0000023` it throws an exception saying there is no bytes in buffer to send (this command is not received in PROCESS function and I had no control over it), which means my card acts toward `0xa0c0` and `0x00c0` the same. So maybe we've used different types of cards? or do you have any better explanation for this? – MFA Jul 21 '15 at 07:41
  • @MFA What kind of tool did you use to send APDU commands to card? It seems that your tool consider `0xa0c0000023` as `CLA=0xA0`, `INS=0xC0`, `P1=0x00`, `P2=0x00` and **Lc = 0x23**, while my tool (OpenSC-Tool) consider it as `CLA=0xA0`, `INS=0xC0`, `P1=0x00`, `P2=0x00` and **Le = 0x23** and as your tool consider `0x23` as `Lc`(Length of APDU Command data field), it expect 0x23 bytes data in buffer to send. Can you try my tool also? – Ebrahim Ghasemi Jul 21 '15 at 10:10
  • Try this two commands instead also : `0xa0c000000023` and `0xa0c0000000000023`. (Those are equal with `CLA|INS|P1|P2|Lc|Le` for short APDU commands and `CLA|INS|P1|P2|Lc1|Lc2|Lc3|Le` for extended APDU commands in some tools.) – Ebrahim Ghasemi Jul 21 '15 at 10:12
  • My mistake was in calling `setIncomingAndReceive()` regardless of command byte. conditioned that line to `CLA` and it's working like a charm. – MFA Jul 22 '15 at 11:53