Showing posts with label dev. Show all posts
Showing posts with label dev. Show all posts

21 Oct 2012

JavaCard STK usage example: One Time Password


Today I'd like to show you one of the ways of JavaCard STK applet usage. In the world of information systems a good authentication procedure is one of the most important topics. And one of the most reliable ways to do it is two factor authentication usage. The most known two factor authentication is One Time Password (OTP).

OTP - is a password which is valid only for one authentication session. Password validity could be also limited in time. The advantage of One Time Password is inability to
use the same password twice. Hence if password is intercepted somehow it will be useless.

The aim of this post is not to give you all pros and cons of OTP. I'll let my reader dig it on his own :) Instead I want to show you how OTP could be implemented in JavaCard STK applet.

The main problem of OTP for end-users is inability to keep in mind all One Time Passwords therefore we need some additional device to generate it on the fly - JavaCard STK applet.

Let's have a look how we can do it. First of all we will implement 2 menu items for Init key and Get next password as:

/**
 * Constructor of the applet
 */
public otp() {
    // Get the reference of the applet ToolkitRegistry object
    reg = ToolkitRegistry.getEntry ();

    menuGetNextPasswd = new byte[] { (byte) 'G', (byte) 'e', (byte) 't',
            (byte) ' ', (byte) 'n', (byte) 'e', (byte) 'x', (byte) 't',
            (byte) ' ', (byte) 'p', (byte) 'a', (byte) 's', (byte) 's',
            (byte) 'w', (byte) 'o', (byte) 'r', (byte) 'd' };
    menuInitKey = new byte[] { (byte) 'I', (byte) 'n', (byte) 'i',
            (byte) 't', (byte) ' ', (byte) 'k', (byte) 'e', (byte) 'y' };
    // Define the applet Menu Entry
    idMenuGetNextPasswd = reg
            .initMenuEntry (menuGetNextPasswd, (short) 0,
                            (short) menuGetNextPasswd.length,
                            PRO_CMD_SELECT_ITEM, false, (byte) 0, (short) 0);
    idMenuInitKey = reg
            .initMenuEntry (menuInitKey, (short) 0,
                            (short) menuInitKey.length, (byte) 0, false,
                            (byte) 0, (short) 0);

    // during instantiation of the applet key isn't initialized yet
    isKeyInitialized = false;
    // fixing key length to 20 bytes
    key = new byte[KEY_LENGTH];

    tmpBuf = new byte[KEY_LENGTH_ASCII];
}

Then we have to implement processToolkit() method to treat menu items selections:


public void processToolkit(byte event) {
    EnvelopeHandler envHdlr = EnvelopeHandler.getTheHandler ();

    // Manage the request following the MENU SELECTION event type
    if (event == EVENT_MENU_SELECTION) {
        // Get the selected item
        byte selectedItemId = envHdlr.getItemIdentifier ();

        // Perform the required service following the menuGetNextPasswd
        // selected item
        if (selectedItemId == idMenuGetNextPasswd) {
            getNextPasswd ();
        }

        // Perform the required service following the menuInitKey selected
        // item
        if (selectedItemId == idMenuInitKey) {
            initKey ();
        }
    }
}

The initKey() method will request initial key which will be used for next password calculation. The method getNextPasswd() could be implemented in the following way:


/**
 * Manage the menuGetNextPasswd selection
 */
private void getNextPasswd() {
    if (isKeyInitialized) {
        try {
            hash = MessageDigest.getInstance (MessageDigest.ALG_SHA, true);
            hash.doFinal (key, (short) 0, (short) key.length
                         , tmpBuf, (short) 0);
            Util.arrayCopyNonAtomic (tmpBuf, (short) 0, key, (short) 0,
                                     (short) key.length);
            displayHexBuffer (key, (short) key.length);
        } catch (CryptoException e) {
        }
    } else {
        displayText(msgKeyNotInited);
    }
    return;
}

After password generation we need to verify it somehow on the server side. Let's implement authentication server simulator. I'll show you only proof-of-concept implementation, a simple GUI application wich requires password and verifies it. It looks like this:



I've used Clojure for it:


(def md (MessageDigest/getInstance "SHA-1"))

(defn ascii2hex [ascii-str]
  (map #(Integer/parseInt % 16) (map #(apply str %) (partition 2 ascii-str))))

(defn bytes2hexStr [bytes]
  (apply str
         (map #(.toUpperCase %)
              (map #(format "%02x" %)
                   (map #(bit-and 0xFF %) (seq bytes))))))

(defn get-next-password [key-str]
  (. md reset)
  (bytes2hexStr
   (seq
    (. md digest
       (into-array Byte/TYPE
                   (map #(.byteValue %)
                        (ascii2hex key-str)))))))

The full source code of the applet and authentication server simulator could be found on my GitHub page.

Peace on you! :)


14 Sept 2012

MIFARE password calculator (Clojure edition)

Wow! I didn't updated my blog almost a year already. I have to fix it. :)
After switched to Macbook at home I decided to review my development tools and also programming languages. As an exercise I redeveloped my MIFARE password calculator in Clojure. Now you don't need dotNET framework to run it. Just download standalone version of JAR file and run it as:
java -jar <jarfilename>
I hope it will be more useful.
You can download it from GitHub.
New posts on different topics are coming soon. Stay tuned! ;)

Update: Add links to previous posts on the same topic:

22 Apr 2011

Unusual usage of exceptions in JavaCard development (Updated)

If you are reading this blog most probably you already know that development of JavaCard applets has own specificities. Sometimes we need to save few bytes to fit applet to card memory and speed of applet is always important. In this post I’d like to show you unusual usage of exceptions to optimize speed and size of the applet.
Let’s imagine you need to read transparent file on the card but you don’t know its size in advance. Usual practice is analyzing response to select and extracting size information. In our test case we have to read PLMNSel file which contains Mobile Network Code and Mobile Country Code. Each PLMN information length is 3 bytes. Afterwards we can do something with this information but I skip it to show you the main idea. Let's have a look to the code:

package testappletwithbuffer;

import sim.access.*;
import javacard.framework.*;

public class TestAppletWithBuffer extends javacard.framework.Applet {
    
    private SIMView gsmFile;
    private byte[] plmn;
    private byte[] response;
    
    protected TestAppletWithBuffer() {
        gsmFile = SIMSystem.getTheSIMView ();
        plmn = new byte[3];
        response = new byte[15];
    }

    public static void install(byte[] bArray, short bOffset, byte bLength){
        TestAppletWithBuffer refApplet = new TestAppletWithBuffer();
        refApplet.register(bArray, (short) (bOffset + 1), (byte) bArray[bOffset]);
        refApplet.readPLMNSel();
    }

    public void process(APDU apdu) throws ISOException {
          // ignore the applet select command dispatched to the process
        if (selectingApplet()) {
            return;
        }
    }
    
    public void readPLMNSel() {
        gsmFile.select ((short) SIMView.FID_DF_GSM);
        gsmFile.select ((short) SIMView.FID_EF_PLMNSEL
                        , response
                        , (short) 0
                        , (short) response.length);
        short fileOffset = 0;
        short fileLength = Util.makeShort(response[2], response[3]);
        
        // reads the PLMN information to plmn buffer
        for (fileOffset = 0; fileOffset < fileLength; fileOffset += plmn.length) {
            gsmFile.readBinary (fileOffset
                                , plmn
                                , (short) 0
                                , (short) plmn.length);
        }

    }
}

Let me show you how we can optimize this applet:

package testappletwithexception;

import sim.access.*;
import javacard.framework.*;

public class TestAppletWithException extends javacard.framework.Applet {

    private SIMView gsmFile;
    private byte[] plmn;

    public TestAppletWithException() {
        gsmFile = SIMSystem.getTheSIMView();
        plmn = new byte[3];
    }

    public static void install(byte[] bArray, short bOffset, byte bLength) {
        TestAppletWithException refApplet = new TestAppletWithException();
        refApplet.register(bArray, (short) (bOffset + 1), (byte) bArray[bOffset]);
        refApplet.readPLMNSel();
    }

    public void process(APDU apdu) {
        // ignore the applet select command dispatched to the process
        if (selectingApplet()) {
            return;
        }
    }
    
    public void readPLMNSel() {
        short fileOffset = 0;
        gsmFile.select ((short) SIMView.FID_DF_GSM);
        gsmFile.select ((short) SIMView.FID_EF_PLMNSEL);
        
        try {
            // reads the PLMN information to plmn buffer
            for (fileOffset = 0; fileOffset < (short) 0xFFFF; fileOffset += plmn.length) {
                gsmFile.readBinary(fileOffset
                                   , plmn
                                   , (short) 0
                                   , (short) plmn.length);   
            }
        } catch (SIMViewException e) {
            // normal case
        }
    }
}

Such kind of usage of exception could be weird to regular Java developers. But compare generated bytecodes:

Applet with exception Applet with buffer
.method public readPLMNSel()V 8 {
    .stack 5;
    .locals 1;

    L0:  sconst_0;
         sstore_1;
         getfield_a_this 0;  // ref gsmFile
      sspush 32544;
         invokeinterface 2 10 7; // SIMView
         getfield_a_this 0;  // ref gsmFile
         sspush 28464;
         invokeinterface 2 10 7; // SIMView
    L1:  sconst_0;
         sstore_1;
         goto L3;
    L2:  getfield_a_this 0; // ref gsmFile
         sload_1;
         getfield_a_this 1; // ref plmn
         sconst_0;
         getfield_a_this 1; // ref plmn
         arraylength;
         invokeinterface 5 10 9; // SIMView
         pop;
         sload_1;
         getfield_a_this 1; // ref plmn
         arraylength;
         sadd;
         sstore_1;
    L3:  sload_1;
         sconst_m1;
         if_scmplt L2;
    L4:  goto L6;
    L5:  pop;
    L6:  return;
    .exceptionTable {
         // start_block end_block
         // handler_block catch_type_index
         L1 L4 L5 9;
    }
}
.method public readPLMNSel()V 8 {
    .stack 5;
    .locals 2;

    L0:  getfield_a_this 0;  // ref gsmFile
         sspush 32544;
         invokeinterface 2 10 7; // SIMView
         getfield_a_this 0;  // ref gsmFile
         sspush 28464;
         getfield_a_this 2;  // ref response
         sconst_0;
         getfield_a_this 2;  // ref response
         arraylength;
         invokeinterface 5 10 6; // SIMView
         pop;
         sconst_0;
         sstore_1;
         getfield_a_this 2;  // ref response
         sconst_2;
         baload;
         getfield_a_this 2;  // ref response
         sconst_3;
         baload;
         invokestatic 11;  // makeShort
         sstore_2;
         sconst_0;
         sstore_1;
         goto L2;
    L1:  getfield_a_this 0;  // ref gsmFile
         sload_1;
         getfield_a_this 1;  // ref plmn
         sconst_0;
         getfield_a_this 1;  // ref plmn
         arraylength;
         invokeinterface 5 10 9; // SIMView
         pop;
         sload_1;
         getfield_a_this 1;  // ref plmn
         arraylength;
         sadd;
         sstore_1;
    L2:  sload_1;
         sload_2;
         if_scmplt L1;
    L3:  return;
}

As you can see exception bytecode shorter and (here you have to trust me :)) it will work faster.

In given example bytecode size isn’t noticeably less but if you have more complex logic of verification it could make sense. If you compile to above two applets and compare size of IJC files it will be 339 and 363 bytes accordingly. So you will save 24 bytes and will win a little on speed.

Update:
After publishing post I figured out how to more optimize the version with exception. Actually we don't need to check anything at all and if we will replace for loop with while like below we will win even more on the size and speed:

while(true) {
    gsmFile.readBinary(fileOffset
                       , plmn
                       , (short) 0
                       , (short) plmn.length);
    fileOffset += plmn.length;
}

And bytecode in this case will be very short:

.method public readPLMNSel()V 8 {
    .stack 5;
    .locals 1;

    L0:  sconst_0;
         sstore_1;
         getfield_a_this 0;  // ref gsmFile
         sspush 32544;
         invokeinterface 2 10 7;  // sim/access/SIMView
         getfield_a_this 0;       // ref gsmFile
         sspush 28464;
         invokeinterface 2 10 7;  // sim/access/SIMView
    L1:  getfield_a_this 0;       // ref gsmFile
         sload_1;
         getfield_a_this 1;       // ref plmn
         sconst_0;
         getfield_a_this 1;       // ref plmn
         arraylength;
         invokeinterface 5 10 9;  // sim/access/SIMView
         pop;
         sload_1;
         getfield_a_this 1;       // ref plmn
         arraylength;
         sadd;
         sstore_1;
         goto L1;
    L2:  pop;
         return;
    .exceptionTable {
        // start_block end_block handler_block catch_type_index
        L1 L2 L2 9;
    }
}
So there is no limit for perfection :)
Update 2:
I've decided do not leave you with the statement "just trust me" concerning the speed. Let me explain why it is faster:
  • There is no implicit garbage collection on JavaCard. You have to call it explicitly hence no need to unwind stack during exception
  • Exceptions are not fully object as in terms of "big" Java. Usually it is just error code from native layer
As matter of fact usage of exceptions is cheap in JavaCard

10 Dec 2010

How to access to MIFARE memory

To be able to read/write to/from MIFARE memory there is javacardx.external package specified in JavaCard 2.2.2 standard.
It specifies MemoryAccess interface and Memory class.
First we have to get object of MemoryAccess object like:

oMemAccess = Memory.getMemoryAccessInstance(Memory.MEMORY_TYPE_MIFARE
                                          , null
                                          , (short)0);


Memory.getMemoryAccessInstance() method has the following parameters:
  • memoryType - the desired external memory subsystem. Could be MEMORY_TYPE_MIFARE or MEMORY_TYPE_EXTENDED_STORE.
  • memorySize - the array containing the desired size in bytes, if applicable, in the external memory subsystem. This parameter is ignored for MIFARE memory type.
  • memorySizeOffset - the offset within the memorySize array where the 32 bit memory size number in bytes is specified. This parameter is ignored.
As you can see from above parameters list we need only specify memory type to get access MIFARE memory.
Then to write data to we can use MemoryAccess.writeData() method like:

oMemAccess.writeData(
             dataToWrite                     // the source data byte array
           , (short) 0                       // the byte offset in data buffer
           , (short) dataToWrite.length      // the length of data
           , thisCardPwdArray                // the byte array containing the 
                                             // key (password)
           , (short)0                        // the byte offset into the key 
                                             // array where the key data begins
           , (short) thisCardPwdArray.length // the length in bytes of key
           , (short) (blocknum / 4)          // sector number
           , blocknum)                       // block number

I'd like to mention one point about sector and block numbers. There are 2 type of addressing mode:

  • Absolute mode where block number accepts values 0..63 and sector number will be ignored.
  • Relative mode where block number accepts values 0..4 and sector number must be correctly set according to MIFARE memory layout.
To read data there is the method MemoryAccess.readData():


oMemAccess.readData(
               readBuf                         // destination buffer
             , (short) 0                       // offset in destination buffer
             , thisCardPwdArray                // key (password) array
             , (short)0                        // offset in key array
             , (short) thisCardPwdArray.length // key length
             , (short)secnum                   // sector number
             , (short)blocknum                 // block number
             , DATA_LEN)                       // number of bytes to read


All parameters have the same meaning as in writeData() method.


One additional remark: if the password to access MIFARE memory is incorrect there is no retry mechanism. You have to start from the beginning. The reason why it has implemented like that is absence of key counter like in PIN key.

3 Dec 2010

Usage of dynamic/diversified data during applet installation

In this post I'd like to talk a little about usage of dynamic/diversified data in install() method of JavaCard applet.

But first let me explain what is dynamic/diversified data is. It is pretty simple. If you are reading some file during applet installation and this file content is different from one card to another you are using dynamic data. As an example of such kind of data could be ICCID or IMSI of the card. The diversified data is the kind of data in the file where you have some master key and for each card you have some generation mechanism which will guarantee uniqueness of each card.

Okay, I do hope it is clear what is dynamic/diversified data is. Now back to the subject of this post. The main message of it is:

 Do not use any dynamic/diversified data during your applet installation! 


Now let me explain why. Most of the (if not all) SmartCard manufacturers are not using regular APDU commands to personalize each card as it is time consuming. Just imagine how much time it will take to produce card by creation of each file with CREATE FILE APDU and then to update its content by UPDATE BINARY/UPDATE RECORD APDU commands if your speed limited with PPS. As each command involves SmartCard Operating System to treat it, to verify all security conditions, to perform required operation. When you have to produce millions of cards per day it is unacceptable. This is why the card production process was splitted to 2 stages:
  • Master card creation 
  • Daughter card creation 
What each stage means.
Master card was created only once for each type of the SmartCard profile and for its creation regular APDU commands were used. Afterwards by special mechanism all dynamic parts which are specific for each card were determined and separated from static part and card memory dumped.

Then for daughter card creation (these is actually cards which will be produced in larges amount) this memory dump is used i.e. instead of sending each APDU command one by one and pushing OS to treat them, production writes directly to card memory. And then the small part which is unique for the each card will be  personalized by regular APDU. That is much faster.

And if you use dynamic data during applet installation it will force your applet installation command to move to dynamic part which is slowing down production process. Moreover it is quite difficult to recognize if your applet is really using dynamic data. If it is just reads it to store inside the applet, the automatic mechanism of detection may not trigger, because memory will be the same. It means if by automatic mechanism your applet is considered as static, your applet will get incorrect data as static part is located before dynamic part.

So, what is the solution if you really need to use dynamic data? Implement it other way round:
  • Post process personalization of the applet by special commands 
  • Get necessary information in runtime 
  • etc. 
Which way is right depends on your applet design and functionality.

22 Nov 2010

JavaCard applets debugging techniques

Debugging JavaCard applets is always difficult. There are different ways of debugging applets:
  • Usage of different simulators
  • Usage of On Card Debugger
  • Applet way of debugging

Let’s review each way one by one.

Simulators
Most of JavaCard development IDEs provides SIM Card Simulator. Two of them are bundled with JavaCard Development Kit. They are CREF and JCWDE. I couldn’t tell too much about them as I’ve never used. Another example is commercial product Developer Suite by Gemalto. It has own different type simulators. Which enables you to debug different applets including Smart Card Web Server (SCWS) servlets and NFC applets.
The simulators are good enough but sometimes you need to debug on real card. The situation when everything is working fine on simulator and not working on the card isn’t rare.
I don’t want to pay a lot attention to simulator as debugging techniques are almost the same as any other application.

On Card Debugger
This is most advanced way of debugging applets but at the same time least available. Each SmartCard manufacturer has own On Card Debugger implementation and usage of it is subject of property. It is not available outside of the manufacturer.
But anyway let me explain general approach of On Card Debugger usage. Most of them are based on Remote Java Debugging. To use it you have to follow below actions:

  • Compile your applet with Debug_Component (Be careful, Debug_Component is only available starting from JavaCard 2.2.1). To be able to do it you have to compile all your classes with debug information and use –debug option during conversion
  • Load applet to the card
  • Setup your favourite development environment for Remote Java Debugging
  • Activate On Card Debugger if needed

I can’t say more on this subject as I have NDA constraints.

Applet way of debugging
This way is most available. The general idea is the same as logging your application steps. I’d like to cover it in details.
There are several ways of applet way of debugging:

  • Throw ISOException.throwIt(0x????) if some verification didn’t pass. As a result you’ll have Status Word for some action of your applet and you can figure out what is going wrong
  • Usage DISPLAY TEXT proactive command to track your applet execution
  • Usage of Shareable interface and communicate with your applet from another one and somehow get execution steps. Here you can use DISPLAY TEXT or you can write to some file.
  • Usage of Debug file directly from your applet. You can write logs to this file
  • You can create your own APDU commands and implement process() method
  • Combination of above steps

Personally I prefer combination of DISPLAY TEXT and creation of own APDUs with implementation of process() method.

Let’s review this method step by step.

The main idea of this debugging techniques is writing specific values to global variables at different part of the code execution and retrieve those values when needed.

With these values we can deduce:

  • The last correctly executed line
  • What kind of exception has thrown and and its reason

We can retrieve those values in 2 different ways:

  • By selection of STK menu
  • By selecting directly applet AID and send appropriate APDU

How can we implement it? We can declare bunch of static variables to store debug values like:

private static byte bDebug1 = (byte)0;
private static byte bDebug2 = (byte)0;
private static byte bDebug3 = (byte)0;
private static byte bDebug4 = (byte)0;
private static byte bDebug5 = (byte)0;
private static byte bDebug6 = (byte)0;

Then we need to implement setDebug() method like:

private static void setDebug( short sDebug )
{
    bDebug1 = (byte) (sDebug >> 8);
    bDebug2 = (byte) sDebug;
}
private static void setDebug( short sDebug, short sDebug2 )
{
    bDebug3 = (byte) (sDebug >> 8);
    bDebug4 = (byte) sDebug;
    bDebug5 = (byte) (sDebug2 >> 8);
    bDebug6 = (byte) sDebug2;
}

Now in our target applet which we have to debug we can use it like:

setDebug((short)0x0102);

Where 0x0102 is some coding which specify whatever you want on some stage of execution.

To retrieve values we have to implement process() method like:

/**
* Method called by the JCRE, once selected
* @param apdu the incoming APDU object
*/
public void process(APDU apdu) {
    /** any APDU command to the applet will send back 6 bytes */
    byte [] baAPDU = apdu.getBuffer();

    baAPDU[ ISO7816.OFFSET_CDATA ] = bDebug1;
    baAPDU[ ISO7816.OFFSET_CDATA + 1 ] = bDebug2;
    baAPDU[ ISO7816.OFFSET_CDATA + 2 ] = bDebug3;
    baAPDU[ ISO7816.OFFSET_CDATA + 3 ] = bDebug4;
    baAPDU[ ISO7816.OFFSET_CDATA + 4 ] = bDebug5;
    baAPDU[ ISO7816.OFFSET_CDATA + 5 ] = bDebug6;

    apdu.setOutgoingAndSend( ISO7816.OFFSET_CDATA, (short) 6 );
}

To retrieve debug information through STK menu we have to implement processToolkit() method:

/**
* Method called by the SIM Toolkit Framework
* @param event the byte representation of the event triggered
*/
public void processToolkit(byte event) {
    try {
        EnvelopeHandler envHdlr = EnvelopeHandler.getTheHandler();

        // Manage the request following the MENU SELECTION event type
        if (event == EVENT_MENU_SELECTION) {
            // Get the selected item
            byte selectedItemId = envHdlr.getItemIdentifier();

            // Perform the required service following the Menu1 selected item
            if (selectedItemId == idMenuDisplayDebug) {
                displayDebug();
            }
        }

        // If required by your applet implement managing
        // UNFORMATTED SMS PP ENV event type and
        // FORMATTED SMS PP event type

       if (event == EVENT_UNFORMATTED_SMS_PP_ENV) {
           unformattedSmsDownloadService();
       }
       if (event == EVENT_FORMATTED_SMS_PP_ENV) {
           formattedSmsDownloadService();
       }
    }
    catch(ArrayIndexOutOfBoundsException aioob) {
        setDebug((short)0x0100, (short)0x1111);
    }
    catch(NullPointerException npe) {
        setDebug((short)0x0200, (short)0x1111);
    }
    catch(SecurityException se) {
        setDebug((short)0x0300, (short)0x1111);
    }
    catch(ISOException ie) {
        setDebug((short)0x0400, ie.getReason());
    }
    catch(SIMViewException sve) {
        setDebug((short)0x0500, sve.getReason());
    }
    catch(ToolkitException te) {
        setDebug((short)0x0600, te.getReason());
    }
    //
    // add here any other exceptions
    //
    catch(Exception e) {
        setDebug((short)0x0700, (short)0x1111);
    }
}

The displayDebug() method could be implemented like:

/**
* Manage the debug menu selection
*/
private void displayDebug() {
// Get the received envelope
ProactiveHandler proHdlr = ProactiveHandler.getTheHandler();

baStringDebug[(short)0] = bDebug1;
baStringDebug[(short)1] = bDebug2;
baStringDebug[(short)2] = bDebug3;
baStringDebug[(short)3] = bDebug4;
baStringDebug[(short)4] = bDebug5;
baStringDebug[(short)5] = bDebug6;

// Display the "Menu3" message text
// Initialize the display text command
proHdlr.initDisplayText((byte) 0x00
, DCS_8_BIT_DATA
, baStringDebug
, (short) 0
,(short) (baStringDebug.length));
proHdlr.send();

return;
}

Happy debug! :)

9 Nov 2010

Uncaught exception and Status Word (SW) 6F00

Okay, you have developed applet and trying to load to smart card (hereafter I'll call it SIM Card as it is one of particular usage of Smart Card). But on last INSTALL AND MAKE SELECTABLE APDU you've received 6F00 Status Word (SW). 6F00 SW is not documented by any standard and generally means something wrong with the card. But based on my own experience most of the time it isn't card issue.

So what could be reason of 6F00?

Answer is very simple. Uncaught exception in your constructor or in install() method.

Below an example:

import sim.toolkit.*;
import javacard.framework.*;

public class DummyApplet extends javacard.framework.Applet implements
        ToolkitInterface, ToolkitConstants {
    
    private static byte[] RAM_Buffer; 

    /**
     * Constructor of the applet
     */
    public DummyApplet() {
        register(bArray, (short) (bOffset + 1), (byte) bArray[bOffset]);
        ToolkitRegistry.getEntry();

    }

    /**
     * Method called by the JCRE at the installation of the applet
     * @param bArray the byte array containing the AID bytes
     * @param bOffset the start of AID bytes in bArray
     * @param bLength the length of the AID bytes in bArray
     */
    public static void install(byte[] bArray, short bOffset, byte bLength) {
        // Create the Java SIM toolkit applet
        DummyApplet dummyApplet = new DummyApplet();
        // Register this applet
        dummyApplet.register(bArray, (short) (bOffset + 1),
                (byte) bArray[bOffset]);

        short offsetCI = (short) (bOffset + bArray[bOffset] + 1);
        short paramIdx = (short) (offsetCI + bArray[offsetCI] + 1);
        short bufLength = Util.getShort(bArray, paramIdx);         

        RAM_Buffer = JCSystem.makeTransientByteArray(bufLength, JCSystem.CLEAR_ON_RESET);
        
    }
   .....
}


Of course this is really dummy applet but it shows typical JavaCard developers mistake. You have to remember that transient memory (RAM) is very limited on SIM Card and your applet is not alone. Some other applets could already took some part of memory. And probability of getting SystemException.NO_TRANSIENT_SPACE on the line:

RAM_Buffer = JCSystem.makeTransientByteArray(bufLength, JCSystem.CLEAR_ON_RESET);

is very high.

Conclusion: You have to try/catch exceptions in constructor and install() method. If you are allocating some memory buffers check available memory before.

F# Survival Guide

The subj is good introduction to F# programming but it is only available online.

I’ve created offline versions to print:

Original text available on the site.