Hot questions for Using Applets in javacard

Question:

I am quite new to Java Card but after some reading, my first Applet is working quite well.....until today. I refactored a bit and inserted an OwnerPIN object to my Applet. And now I can write the Applet once, but the second time, the deletion does not work anymore. Here is my output:

Java Card 2.2.2 Class File Converter, Version 1.3
Copyright 2005 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms.
mode_201
gemXpressoPro
enable_timer
establish_context
command time: 16 ms
card_connect
command time: 187 ms
select -AID A000000018434D00
command time: 78 ms
open_sc -security 1 -keyind 0 -keyver 0 -key 47454d5850524553534f53414d504c45 -keyDerivation visa2
command time: 328 ms
delete -AID  0102030405060708090000
delete() returns 0x80206985 (6985: Command not allowed - Conditions of use not satisfied.)
command time: 31 ms
delete -AID  01020304050607080900
delete() returns 0x80206985 (6985: Command not allowed - Conditions of use not satisfied.)
command time: 47 ms
get_status -element e0


List of applets (AID state privileges)
a000000018434d00 1 9e
a0000000620001 1 0
a0000000620002 1 0
a0000000620003 1 0
a0000000620101 1 0
a000000062010101 1 0
a0000000620102 1 0
a0000000620201 1 0
a0000000620209 1 0
a0000000620202 1 0
a000000018100109 1 0
a00000001810010b 1 0
a00000001810010a 1 0
a0000000030000 1 0
a000000018100106 1 0
a000000018100201 1 0
a000000018100101 1 0
a00000015100 1 0
a000000018100108 1 0
a0000000181001ff 1 0
a000000018100501 1 0
a000000018100502 1 0
a000000018100401 1 0
5365637572697479 1 0
a0000000035350 1 0
01020304050607080900 1 0
0102030405060708090000 7 0
command time: 187 ms
install -file mycap.cap -sdAID A000000018434D00 -nvCodeLimit 4096 -instParam 2265
install_for_load() returns 0x80206985 (6985: Command not allowed - Conditions of use not satisfied.)

update As requested, parts of my code:

public class MyApplet extends Applet
{

   private static final byte MY_CLA = (byte)0xB0;

  ...
    private final static byte VERIFY_INS = (byte)0x40;
 ...
    private final static byte NEED_VERIFICATION_INS = (byte)0x47;
    private final static byte GET_INSTALL_PARAMS_INS = (byte)0x50;
    private final static byte GET_REMAINING_PIN_TRIES_INS = (byte)0x60;

    private final static byte PIN_TRY_LIMIT = (byte)0x03;
    private final static byte MAX_PIN_SIZE = (byte)0x08;

    // signal that the PIN verification failed
    private final static short SW_VERIFICATION_FAILED = 0x6300;
    private final static short SW_PIN_VERIFICATION_REQUIRED = 0x6301;

   ...
    private static byte[] testdata;
    private OwnerPIN m_pin;
    private byte[] m_array;
    private short m_offset;
    private byte m_length;

    private MyApplet(byte[] bArray, short bOffset, byte bLength)
    {
       ...
        m_pin = new OwnerPIN(PIN_TRY_LIMIT, MAX_PIN_SIZE);
        // m_array = bArray;
        // m_offset = bOffset;
        // m_length = bLength;
        register();
    }

    public boolean select()
    {
        if (m_pin.getTriesRemaining() == 0)
        {
            return false;
        }
        return true;
    }

    public void deselect()
    {
        m_pin.resetAndUnblock();
    }

    private void adminRest()
    {
        m_pin.resetAndUnblock();
        return;
    }


    private void getInstallParams(APDU apdu)
    {
        try
        {
            byte[] buffer = apdu.getBuffer();
            // inform the JCRE that the applet has data to return
            short le = apdu.setOutgoing();
            // set the actual number of the outgoing data bytes
            apdu.setOutgoingLength(((short)testdata.length));
            apdu.sendBytesLong(testdata, (short)0, (short)testdata.length);

        }
        catch (APDUException e)
        {
            // TODO Auto-generated catch block
        }
        catch (TransactionException e)
        {
            // TODO Auto-generated catch block
        }
        catch (ArrayIndexOutOfBoundsException e)
        {
            // TODO Auto-generated catch block
        }
        catch (NullPointerException e)
        {
            // TODO Auto-generated catch block
        }
    }

    /**
     * Get number of remaining pin tries
     * 
     * @param apdu
     */
    private void getPinTriesRemaining(APDU apdu)
    {
        try
        {
            byte[] buffer = apdu.getBuffer();
            // inform the JCRE that the applet has data to return
            apdu.setOutgoing();
            // set the actual number of the outgoing data bytes
            apdu.setOutgoingLength((byte)2);

            // write the PinTriesRemaining into the APDU buffer at the offset 0
            Util.setShort(buffer, (short)0, m_pin.getTriesRemaining());

            // send the 2-byte balance at the offset
            // 0 in the apdu buffer
            apdu.sendBytes((short)0, (short)2);
        }
        catch (APDUException e)
        {
            // TODO Auto-generated catch block
        }
        catch (TransactionException e)
        {
            // TODO Auto-generated catch block
        }
        catch (ArrayIndexOutOfBoundsException e)
        {
            // TODO Auto-generated catch block
        }
        catch (NullPointerException e)
        {
            // TODO Auto-generated catch block
        }

    } // end of getPinTriesRemaining method

    /**
     * Verification method to verify the PIN
     * 
     * @param apdu
     */
    private void verify(APDU apdu)
    {

        byte[] buffer = apdu.getBuffer();

        // receive the PIN data for validation.
        byte byteRead = (byte)(apdu.setIncomingAndReceive());

        // check pin
        // the PIN data is read into the APDU buffer
        // starting at the offset ISO7816.OFFSET_CDATA
        // the PIN data length = byteRead
        if (!m_pin.check(buffer, ISO7816.OFFSET_CDATA, byteRead))
        {
            ISOException.throwIt(SW_VERIFICATION_FAILED);
        }

    } // end of verify method

    /**
     * Installs the applet.
     *
     * @param bArray array with installation parameters.
     * @param bOffset offset into array.
     * @param bLength the length of the parameters.
     */
    public static void install(byte[] bArray, short bOffset, byte bLength)
    {
        testdata = new byte[bLength];
        Util.arrayCopy(bArray, (short)0, testdata, (short)0, bLength);
        new MyApplet(bArray, bOffset, bLength);
    }


    /**
     * Processes an incoming APDU.
     *
     * @param apdu the APDU.
     */
    public void process(APDU apdu)
    {

        byte l_transferredBuffer[] = apdu.getBuffer();
        // Get the CLA; mask out the logical-channel info.
        l_transferredBuffer[ISO7816.OFFSET_CLA] = (byte)(l_transferredBuffer[ISO7816.OFFSET_CLA] & (byte)0xFC);
        if ((l_transferredBuffer[ISO7816.OFFSET_CLA] == 0) && (l_transferredBuffer[ISO7816.OFFSET_INS] == (byte)(0xA4)))
        {
            ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
        }
        if (l_transferredBuffer[ISO7816.OFFSET_CLA] != MY_CLA)
        {
            ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
        }

        byte l_ins = l_transferredBuffer[ISO7816.OFFSET_INS];

      ...
        else if (l_ins == VERIFY_INS)
        {
            verify(apdu);
        }
        ...
        else if (l_ins == NEED_VERIFICATION_INS)
        {
            isNeedVerification(apdu, l_transferredBuffer);
        }
        else if (l_ins == GET_INSTALL_PARAMS_INS)
        {
            getInstallParams(apdu);
        }
        else if (l_ins == GET_REMAINING_PIN_TRIES_INS)
        {
            getPinTriesRemaining(apdu);
        }
        else
        {
            ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
        }
    }

    private void isNeedVerification(APDU apdu, byte[] buffer)
    {
        // The structure for the response request is
        // ---------------------
        // | response |
        // | 1 byte |
        // ---------------------
        getRequest(apdu, buffer);
        byte[] l_needVerificationResponse = new byte[1];
        boolean l_validated = m_pin.isValidated();
        if (l_validated)
        {
            l_needVerificationResponse[0] = 1;
        }
        else
        {
            l_needVerificationResponse[0] = 0;
        }
        apdu.setOutgoing();
        apdu.setOutgoingLength((short)l_needVerificationResponse.length);
        apdu.sendBytesLong(l_needVerificationResponse, (short)0, (short)l_needVerificationResponse.length);
    }

    private byte[] getRequest(APDU apdu, byte[] transferredBuffer)
    {
        short l_setIncomingAndReceive = apdu.setIncomingAndReceive();
        byte[] request = new byte[l_setIncomingAndReceive];
        for (short i = 0; i < request.length; i++)
        {
            short l_j = (short)(ISO7816.OFFSET_CDATA + i);
            request[i] = transferredBuffer[l_j];
        }
        return request;
    }
... 
}

Is my card blocked? I can see that my AID runs in state 7...what does that mean. Is it connected to my OwnerPIN object?

Thanks for your help! Jan


Answer:

The problematic line is this one:

private static byte[] testdata;

Remember, static references to persistent objects are EVIL AND DANGEROUS. They are always there, even after the Applet instance is uninstalled and garbage collected. That is why the referenced object (byte array in your case) is never garbage collected, the persistent memory is never released and thus the deletion command fails.

If you can avoid using static references, do so.

If you cannot avoid it, use AppletEvent interface:

public final class MyApplet extends Applet implements AppletEvent {

    private static byte[] testdata;
    ...

    //This method is called in the moment of uninstallation
    public final void uninstall() {
        testData = null; //release the reference --> testData can be GC
    }
    ...

}

Question:

I am using JCIDE to debug its sample applet- walletdemo.

I encounted error 6985

conditions not satisfied'and 6A88'Referenced data or reference data not found

during installation of the .cap file on the JCVM when debugging. But I don't know what's wrong and what to do.

The following is part of the applet:

private WalletDemoApplet(byte bArray[], short bOffset, byte bLength)
{
   /* cardid=new byte[MAX_NUM_CARDID];
    key  =new byte[MAX_NUM_KEYS];
    for (byte i = 0; i < MAX_NUM_KEYS; i++)
        key[i] =i;
    for (byte i = 0; i < MAX_NUM_CARDID; i++)
        cardid[i] =i;*/

    balance  = 0;
    integral = 0;


    Key = (DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_2KEY, false);         
    //cipherDES_ECB_NOPAD = Cipher.getInstance(Cipher.ALG_DES_ECB_NOPAD, false);
    cipherDES_ECB_NOPAD = Cipher.getInstance(Cipher.ALG_DES_CBC_ISO9797_M1, false);
    myRandomS = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM);

    pin = new OwnerPIN(PIN_TRY_LIMIT,   MAX_PIN_SIZE);
    cardID = new byte[10];
    output = new byte[16];
    //input = new byte[16];
    bRand = false;
    ExternalMark=false;
    verifyMark=false;
    byte iLen = bArray[bOffset]; // aid length
    bOffset = (short) (bOffset+iLen+1);
    byte cLen = bArray[bOffset]; // info length
    bOffset = (short) (bOffset+cLen+1);
    byte aLen = bArray[bOffset]; // applet data length
    bOffset = (short)(bOffset+1);        
    byte pinLen = bArray[bOffset];


    // The installation parameters contain the PIN
    // initialization value
    pin.update(bArray, (short)(bOffset+1), pinLen);

    // Initialize key
    bOffset = (short)(bOffset+pinLen+1);
    byte keyLen = bArray[bOffset];
    Key.setKey(bArray, (short)(bOffset+1));

    // Initialize cardID
    bOffset = (short)(bOffset+keyLen+1);
    byte idLen = bArray[bOffset];
    Util.arrayCopy(bArray, (short)(bOffset+1), cardID, (short)0, (short)idLen); 

    register(); 
}
public static void install(byte[] bArray, short bOffset, byte bLength) {
    // GP-compliant JavaCard applet registration
    new WalletDemoApplet(bArray, bOffset, bLength);

}

Answer:

If the problem is not caused by the algorithm, maybe it's because a installation parameter is required when install.You can try to set the installation parameter, such as “08112233445566778810404142434445464748494A4B4C4D4E4F080010203040506070”.

I hope that i can help you.

Question:

I am a beginner in developpement, i am trying to load stk applet into Sim card, this is my question :

I have an STK applet code source.

I have a smart card reader (gemplus pc/sc)

I have a SIM card and the administration code

I installed eclipse and added JAvaCard and SIM API libraries

when i try to run the applet i get this error :

    Charger : la classe ImsiManager.class est introuvable.
java.lang.ClassNotFoundException: ImsiManager.class
at sun.applet.AppletClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.applet.AppletClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.applet.AppletClassLoader.loadCode(Unknown Source)
at sun.applet.AppletPanel.createApplet(Unknown Source)
at sun.applet.AppletPanel.runLoader(Unknown Source)
at sun.applet.AppletPanel.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

and a appletviewer window appear with " applet non inisialized" as a message.

please can someone help? I need to know how can I load this applet into my sim card ? all suggestions are welcome

Thank you.


Answer:

You can't run SIM applets in Eclipse IDE without using a simulator and you need to use a SIM card simulator (It can be a plugin for your IDE also) or try to run your applet on a real SIM card.

Moreover, for uploading (and installing) your applets, first of all you need to convert that program to a CAP file. There is a tool in Java Card development kit named converter that you can use it to convert applets to CAP files.

Instead of using converter tool directly, you can simply use Eclipse-JCDE plugin to work with this tool and convert your applets.

After converting you need to upload this CAP file on the SIM card. You can use some already-written open source tools to aim this goal. GlobalPlatformPro is well-documented one.

Note that : I'm afraid if the Java Card Development kit is able to convert applets with proprietary SIM APIs to CAP files. but for applets that contains only Java Card API, you can use it simply.

Question:

This post is related to a question I asked a few days ago: Store symmetric keys in Java Card

I want to implement LinkedList in Java Card to store AESKey. So I wrote a class KeyElement this way:

package LinkedList;

import javacard.security.AESKey;
import javacard.security.KeyBuilder;


class KeyElement {
    private KeyElement next;
    private short id;
    private AESKey key;
    private boolean isUsed;

    /**
     * Constructor.
     * 
     * @param upperBound
     *            An upper bound to indicate of many elements it cans contain at
     *            maximum. It is essential to instanciate the structure this way
     *            to reserve all the necessary memory at the installation time.
     */
    public KeyElement(short upperBound) {
       this.id = (short) 0x0000;
       this.key = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES,
           KeyBuilder.LENGTH_AES_256, false);
       this.isUsed = false;
       this.next = null;
       for (short i = (short) 0x0001; i < upperBound; i++) {
           KeyElement e = new KeyElement();
           this.addKeyElement(e);
       }
    }

    public KeyElement() {
       this.id = (short) 0x0000;
       this.key = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES,
           KeyBuilder.LENGTH_AES_256, false);
       this.isUsed = false;
       this.next = null;
    }

    public KeyElement getNext() {
       return this.next;
    }

    public short getID() {
       return this.id;
    }

    public boolean isUsed() {
       return isUsed;
    }

    public void setNext(KeyElement e) {
       this.next = e;
    }

    public static boolean addKey(KeyElement main, final short id, byte[] key) {
       for (KeyElement p = main; p != null; p = p.getNext()) {
            if (!p.isUsed()) {
              p.isUsed = true;
              p.id = id;
              p.key.setKey(key, (short) 0x0000);
              return true;
           }
       }
       return false;
    }



    public void addKeyElement(KeyElement e) {
       e.setNext(this.getNext());
       this.setNext(e);
    }


    public static boolean getKey(final KeyElement e, final short id,
        byte[] key) {
       for (KeyElement p = e; p != null; p = p.getNext()) {
           if (p.id == id) {
              p.key.getKey(key, (short) 0x0000);
              return true;
           }
       }
       return false;
    }
}

And I have an applet LinkedListKey which uses the class KeyElement described before.

package LinkedList;

import javacard.framework.APDU;
import javacard.framework.APDUException;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.PINException;
import javacard.framework.SystemException;
import javacard.framework.TransactionException;
import javacard.framework.Util;
import javacard.framework.service.ServiceException;
import javacard.security.CryptoException;
import javacard.security.RandomData;

public class LinkedListKey extends Applet {

    byte[] rdm;
    RandomData rand;
    KeyElement e;

    private LinkedListKey(final byte[] aidArray, final short aidOffset,
        final byte aidLength, final byte[] dataArray, short dataOffset,
        final short dataLength) throws ISOException {

       e = new KeyElement((short) 0x0064);

       rdm = new byte[(short) 0x0020];

       KeyElement.addKey(e, (short) 0x7514, new byte[] { (byte) 0x75, (byte) 0x14,
        (byte) 0x75, (byte) 0x14, (byte) 0x75, (byte) 0x14,
        (byte) 0x75, (byte) 0x14, (byte) 0x14, (byte) 0x14,
        (byte) 0x75, (byte) 0x14, (byte) 0x75, (byte) 0x14,
        (byte) 0x75, (byte) 0x14, (byte) 0x75, (byte) 0x14,
        (byte) 0x75, (byte) 0x14, (byte) 0x14, (byte) 0x14,
        (byte) 0x75, (byte) 0x14, (byte) 0x75, (byte) 0x14,
        (byte) 0x75, (byte) 0x14, (byte) 0x75, (byte) 0x14,
        (byte) 0x75, (byte) 0x14 });

       register();
    }

    public static void install(final byte[] buffer, short offset,
        final byte length) throws ISOException {
       if (length == 0) {
          ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
       }

       short remainingBytes = makeShort(length);

       // Save instance AID.
       byte aidLength = buffer[offset++];
       short aidOffset = offset;

       // Skip instance AID.
       offset += makeShort(aidLength);

       remainingBytes--;
       remainingBytes -= makeShort(aidLength);

       if (remainingBytes <= (short) 0x0000) {
           ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
       }

       // Skip control data.
       byte infoLength = buffer[offset++];

       offset += makeShort(infoLength);

       remainingBytes--;
       remainingBytes -= makeShort(infoLength);

       if (remainingBytes <= (short) 0x0000) {
           ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
       }

       // Instantiate the application.
       // The length of the application data maybe greater than 127 bytes.
       short dataLength = makeShort(buffer[offset++]);

       remainingBytes--;

       if (remainingBytes != dataLength) {
           ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
       }

       new LinkedListKey(buffer, aidOffset, aidLength, buffer, offset,
           dataLength);
    }

    public void process(final APDU apdu) throws ISOException {
       byte[] apduBuffer = apdu.getBuffer();

       if (selectingApplet()) {
           apdu.setOutgoingAndSend((short) 0x0000, (short) 0x0019);

           return;
        }

    // Send result.
    try {
        if (apduBuffer[ISO7816.OFFSET_INS] == (byte) 0x00) {
           for (short i = 0x0000; i < (short) 0x0008; i++) {
               rand.generateData(rdm, (short) 0x0000, (short) rdm.length);
               KeyElement.addKey(e, i, rdm);
           }
           KeyElement.addKey(e, (short) 0x7503, new byte[] { (byte) 0x75, (byte) 0x03,
            (byte) 0x75, (byte) 0x03, (byte) 0x75, (byte) 0x03,
            (byte) 0x75, (byte) 0x03, (byte) 0x14, (byte) 0x03,
            (byte) 0x75, (byte) 0x03, (byte) 0x75, (byte) 0x03,
            (byte) 0x75, (byte) 0x03, (byte) 0x75, (byte) 0x03,
            (byte) 0x75, (byte) 0x03, (byte) 0x14, (byte) 0x03,
            (byte) 0x75, (byte) 0x03, (byte) 0x75, (byte) 0x03,
            (byte) 0x75, (byte) 0x03, (byte) 0x75, (byte) 0x03,
            (byte) 0x75, (byte) 0x03 });
        }
        else if (apduBuffer[ISO7816.OFFSET_INS] == (byte) 0x01){
           KeyElement.getKey(e, (short) 0x7503, apduBuffer);
           setOutgoingAndSend((short) 0x0000, (short) 0x0020);
        }
        else {
           KeyElement.getKey(e, (short) 0x7514, apduBuffer);
           setOutgoingAndSend((short) 0x0000, (short) 0x0020);
        }
    } catch (ArithmeticException e) {
        ISOException.throwIt((short) 0x0100);
    } catch (ArrayStoreException e) {
        ISOException.throwIt((short) 0x0200);
    } catch (APDUException e) {
        ISOException.throwIt(Util.makeShort((byte) 0x03,
            (byte) e.getReason()));
    } catch (CryptoException e) {
        ISOException.throwIt(Util.makeShort((byte) 0x04,
            (byte) e.getReason()));
    } catch (ISOException e) {
        ISOException.throwIt(Util.makeShort((byte) 0x05,
            (byte) e.getReason()));
    } catch (PINException e) {
        ISOException.throwIt(Util.makeShort((byte) 0x06,
            (byte) e.getReason()));
    } catch (ServiceException e) {
        ISOException.throwIt(Util.makeShort((byte) 0x07,
            (byte) e.getReason()));
    } catch (SystemException e) {
        ISOException.throwIt(Util.makeShort((byte) 0x08,
            (byte) e.getReason()));
    } catch (TransactionException e) {
        ISOException.throwIt(Util.makeShort((byte) 0x09,
            (byte) e.getReason()));
    } catch (ClassCastException e) {
        ISOException.throwIt((short) 0x0A00);
    } catch (IndexOutOfBoundsException e) {
        ISOException.throwIt((short) 0x0B00);
    } catch (NegativeArraySizeException e) {
        ISOException.throwIt((short) 0x0C00);
    } catch (NullPointerException e) {
        ISOException.throwIt((short) 0x0D00);
    } catch (SecurityException e) {
        ISOException.throwIt((short) 0x0E00);
    } catch (RuntimeException e) {
    }
 }


    static private short makeShort(final byte value) {
    return Util.makeShort((byte) 0x00, value);
    }

    private void setOutgoingAndSend(final short dataOffset, short dataLength) throws ISOException {
    APDU.getCurrentAPDU().setOutgoingAndSend(dataOffset, dataLength);
    }
}

So I wrote if/else conditions to bench how many time it takes to:

  • Fill the list (INS = 0x00)
  • get the last element of the list (when INS = 0x01)
  • get the first element of the list (when INS = 0x02)

So with the code given above, I can install my applet on a Java Card without problems.

But when I run my applet, I get an exception 0x0D00 which makes reference to a NullPointerException.

So, what? Do I have to conclude that my KeyElement object instanciation failed? But, as it's made at the installation time, I thought it should return me an error during the installation but it didn't.

More precisely it fails at step:

// Send result.
 try {
   if (apduBuffer[ISO7816.OFFSET_INS] == (byte) 0x00) {
      for (short i = 0x0000; i < (short) 0x0008; i++) {
         rand.generateData(rdm, (short) 0x0000, (short) rdm.length);
         KeyElement.addKey(e, i, rdm);
      }
...

And more precisely at KeyElement.addKey(e, i, rdm); that's why it seems that e raises the NullPointerException even the installation was sucessfull...


Answer:

You have not create the instance of rand, which generates the NullPointerException. You need to use:

RandomData.getInstance(byte algorithm) 

with algorithm

public static final byte    ALG_PSEUDO_RANDOM   1
public static final byte    ALG_SECURE_RANDOM   2

Question:

I'm a newbie to Java Card technology, and I just started reading about it. I want to create a smart applet for my card. My goal is for it to work on card used contactlessly. I downloaded jar file (GlobalPlatformPro) to install *.cap file on card using NFC Card Reader ACR122. But unfortunately I got an error:

Exception in thread "main" java.lang.IllegalArgumentException: apdu must be at least 2 bytes long
        at javax.smartcardio.ResponseAPDU.check(ResponseAPDU.java:73)
        at javax.smartcardio.ResponseAPDU.<init>(ResponseAPDU.java:67)
        at sun.security.smartcardio.ChannelImpl.transmit(ChannelImpl.java:91)
        at pro.javacard.gp.GlobalPlatform.select(GlobalPlatform.java:203)
        at pro.javacard.gp.GPTool.main(GPTool.java:334)

My first question is, is it possible to write an applet using this reader? And secondly how you would recommend doing this?


Answer:

The problem is you are trying to upload an applet to a card, which does not support Global Platform nor Java Card. Mifare 1K is a simple data storage, it can hold some data you write in using its proprietary API. It cannot run any applets, this card is not "smart".

The error message says the response APDU is shorter than expected. Mifare responses do not follow ISO7816, the response status consists of just one byte only, although ISO7816 expects at least two byte long status word.

Look for another card. It should support JCOP, that is the keyword to search.

Question:

I'm relatively new to eclipse and I need to develop a Javacard Application. I got eclipse neon and JDK8 + Java card developement Kit. I've done all the tutorial installation untill this page (included) https://docs.oracle.com/javacard/3.0.5/guide/eclipse_java_card_plug-in.htm#JCUGC127 but when I import a project sample from the javacard directory it tells me (for example for Hello World one):

APDU cannot be resolved to a type   
HelloWorld.java /HelloWorld/applet/src/com/sun/jcclassic/samples/helloworld line 65 Java Problem
Applet cannot be resolved to a type HelloWorld.java /HelloWorld/applet/src/com/sun/jcclassic/samples/helloworld line 29 Java Problem
ISO7816 cannot be resolved to a variable    HelloWorld.java /HelloWorld/applet/src/com/sun/jcclassic/samples/helloworld line 69 Java Problem
ISO7816 cannot be resolved to a variable    HelloWorld.java /HelloWorld/applet/src/com/sun/jcclassic/samples/helloworld line 70 Java Problem
ISO7816 cannot be resolved to a variable    HelloWorld.java /HelloWorld/applet/src/com/sun/jcclassic/samples/helloworld line 78 Java Problem
ISO7816 cannot be resolved to a variable    HelloWorld.java /HelloWorld/applet/src/com/sun/jcclassic/samples/helloworld line 80 Java Problem
The import javacard cannot be resolved  HelloWorld.java /HelloWorld/applet/src/com/sun/jcclassic/samples/helloworld line 20 Java Problem
The import javacard cannot be resolved  HelloWorld.java /HelloWorld/applet/src/com/sun/jcclassic/samples/helloworld line 21 Java Problem
The import javacard cannot be resolved  HelloWorld.java /HelloWorld/applet/src/com/sun/jcclassic/samples/helloworld line 22 Java Problem
The import javacard cannot be resolved  HelloWorld.java /HelloWorld/applet/src/com/sun/jcclassic/samples/helloworld line 23 Java Problem
The import javacard cannot be resolved  HelloWorld.java /HelloWorld/applet/src/com/sun/jcclassic/samples/helloworld line 24 Java Problem
The method register() is undefined for the type HelloWorld  HelloWorld.java /HelloWorld/applet/src/com/sun/jcclassic/samples/helloworld line 38 Java Problem
Util cannot be resolved HelloWorld.java /HelloWorld/applet/src/com/sun/jcclassic/samples/helloworld line 78 Java Problem

And I got similar output with the other projects. I tried some "solutions" i googled like cleaning the project,etc but no one solved the issue. I'd appreciate some tips of what might be happening and what do I have to do.

Thanks in advance.


Answer:

Add api_xxx.jar to your project "Java build path"; The library "api_xxx.jar" is located at JCKit_Dir/lib/.

Question:

I am trying to develop an applet in JavaCard which will have to compute operations with big values (500bits approximately). In more detail, I need to do an addition and a multiplication.

As I am using JavaCard 2.2.2, my big values can only be represented by an array of bytes or an array of shorts.

My question is the following : if I define how to do a multiplication and an addition of two arrays like described above, could I develop an applet to do what I want ?

Thank you very much to help me :)


Answer:

use javacards BigNumber to calculate the operations and then store with the toBytes function.