9 Feb 2011

And then there's Haskell...

> Odd that this has come up -- I was just looking at Common Lisp and
> Scheme implementations, as well as a smattering of Haskellish tools

And then there's Haskell...

Haskell is like "that girl."  You know the one...

You never really went steady, but you'd run into her from time to  
time while knocking around in disreputable joints, usually late at  
night, every several months or so.  She looked so hot, so sleek, so  
sexy, so expressive, so exotic.  You'd end up back at her place and  
the night would just...  take off.  A complete blur of hot, sweaty,  
feverish, delirious, fumbling passion.  You'd do things to each  
other...  you'd do things to her, she'd do things to you...  things  
that you're not even sure have names, that you're pretty sure are  
illegal almost anywhere.  Even her kinks have kinks --- and after one  
of these nights, you'd realize that you yourself had a lot more kinks  
than you.  And it wasn't just physical, it was --- cerebral.   
Ethereal.  Transcendent.  But it would all whiz by in a blur, and by  
morning you'd find yourself lightheaded, a bit confused, and  
stumbling homeward to your regular gal.

Over the next few days and weeks you'd find yourself occasionally  
drifting away, thinking about her.  Haskell.  You'd be there, banging  
away at your regular girl, and find yourself thinking "you know, if I  
was with Haskell, I'd be doing this completely differently."  You'd  
think "I could be doing so much bigger and better stuff with  
Haskell."  Now, your regular girl, she's not as exotic as Haskell.   
Pretty, maybe, if you're lucky.  (Perhaps your regular girlfriend's  
name is Python. ;-)  But not nearly as --- weird.  Wild.  Cool.   
Exciting.  Don't get me wrong --- your girl, she's wonderful.  You've  
got a wonderful relationship.  She's --- comfortable.  You can bang  
away at her all day and night.  She's accommodating.  Easy going.   
You work well together.  But --- confidentially --- she's, well,  
maybe just a little bit boring.  You'd catch yourself thinking these  
things, and the guilty pangs would get to you...  You'd quash the  
thoughts, buckle down, and get back to banging away.  Comfortable...   
there's a lot to be said for that, ya know?  Comfortable...  just  
keep telling yourself that.

Months would go by.  Late some night you'd find yourself out,  
disreputable places again.  Maybe that hacker bar, LtU.  Somebody'd  
slip you an URL for some renegade paper, you know, one of *those*  
papers.  You'd run into Haskell again.  And the whole thing starts over.

Eventually, you're going to get the ultimatum.  Haskell's ultimately  
just like any other girl on some level;  she needs commitment.   
Eventually, after one night of wild, feverish, kinky, abstract  
passion, she's going to say to you:  "All these times, and you don't  
understand me at all!  You know, you're going to have to get serious,  
mister!  I've got needs, too.  You're going to have to get serious  
about my monads, or that's the last time you're going to play with  
them!  Got it?"

...and then, you've got to make The Choice.

Chances are, you're going to go back to your regular gal.  Haskell's  
just too much for any one man, probably.  She leaves a trail of  
broken, brainy, embittered PhDs and former programmers behind her.   
She ruins you for the RealWorld.  You can ride a while, but you  
probably can't go the distance with her.  Go back to your regular gal  
and try not to think too much about what you've seen.  Done.  Felt.   
Thought.

Maybe you can salvage a little happiness;  but it'll be hard.  After  
all...  you've tasted Haskell.

She's not like anything else.


27 Jan 2011

How to calculate MIFARE password

In my recent post “How to access MIFARE memory” I’ve received question how to calculate MIFARE password. So in this post I would like to explain it.
The calculation of MIFARE password (MF_password) has described in Philips Application Note AN02105. It is generated based on Key A and Key B as showed below:






As you can see it is 3DES algo. The start value is 8 bytes with value 00h.
The keys DKeyA and DKeyB are derived from MIFARE Key A and Key B keys of respective MIFARE sector. But Key A and Key B are 6 bytes long. To be able to use them as 3DES keys the following conventions have defined:


Representation of the MIFARE Sector Trailer:





Representation of bits of the MIFARE Key (each consists of 6 bytes):


BYTE 5 MSB BYTE 4 BYTE 3 BYTE 2 BYTE 1 BYTE 0 LSB
K57 K50 K47 K40 K37 K30 K27 K20 K17 K10 K07 K00

The 6 bytes MIFARE key will be mapped to the 64 bit 3DES keys DKeyB in the following way:

DES KEY BYTE BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0
7 K56 K55 K54 K53 K52 K51 K50 P
6 K46 K45 K44 K43 K42 K41 K40 P
5 K36 K35 K34 K33 K32 K31 K30 P
4 K26 K25 K24 K23 K22 K21 K20 P
3 K16 K15 K14 K13 K12 K11 K10 P
2 K06 K05 K04 K03 K02 K01 K00 P
1 0 K57 K47 K37 K27 K17 K07 P
0 0 0 0 0 0 0 0 P

P in BIT 0 means Parity Bit (not checked).
DKeyA will be generated in the same manner according to below table:

DES KEY BYTE BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0
7 0 0 0 0 0 0 0 P
6 0 K07 K17 K27 K37 K47 K57 P
5 K56 K55 K54 K53 K52 K51 K50 P
4 K46 K45 K44 K43 K42 K41 K40 P
3 K36 K35 K34 K33 K32 K31 K30 P
2 K26 K25 K24 K23 K22 K21 K20 P
1 K16 K15 K14 K13 K12 K11 K10 P
0 K06 K05 K04 K03 K02 K01 K00 P

Some examples:
  • Initial value: 00 00 00 00 00 00 00 00
  • The DES parity bits are regarded as 0
MIFARE KEYS (LSB -> MSB) 3DES KEYS (LSB –> MSB) MF_PASSWORD (LSB –> MSB)
Key A FF FF FF FF FF FF DKeyA FE FE FE FE FE FE 7E 00 0B 54 57 07 45 FE 3A E7
Key B FF FF FF FF FF FF DKeyB 00 7E FE FE FE FE FE FE
Key A A0 A1 A2 A3 A4 A5 DKeyA 40 42 44 46 48 4A 7E 00 8C 7F 46 D7 6C E0 12 66
Key B B0 B1 B2 B3 B4 B5 DKeyB 00 7E 60 62 64 66 68 6A

14 Jan 2011

Advanced JavaCard debugging. (The story of one debug)

Sometimes ago I've written the post about JavaCard applets debugging techniques. In the current post I'd like to narrate story from real life. Actually this post is translation of post in my Russian blog.
Well, the problem which I've encountered was the SIM Toolkit (STK) applet with a couple of menu entries. On the real card when you select one of menu entry applet silently exits instead of sending SMS. Checking source code of the applet was not helped. So the only way to debug was loading applet to Software Simulator.
Ok, if no other way, I've compiled the most similar configuration of simulator to real card, created file system, loaded applet. I’ve connected Mobile Phone Simulator to OS Simulator and start browsing menu. When I’ve selected menu item which doesn’t work JCRE log has the following:
// Byte code dump, some part has skipped
CAP[1] - 0x4aac11: SAND
CAP[1] - 0x4aac12: SADD
CAP[1] - 0x4aac13: S2B
CAP[1] - 0x4aac14: BASTORE
CAP[1] - 0x4aac15: ALOAD_0
CAP[1] - 0x4aac16: SCONST_5
CAP[1] - 0x4aac17: SCONST_0
CAP[1] - 0x4aac18: INVOKESTATIC [0x1c 0x24]
LIB[7] - 0x4987eb: SCONST_5
LIB[7] - 0x4987ec: SLOAD_0
LIB[7] - 0x4987ed: INVOKESTATIC [0x1c 0x17]
Calling nativeMethod[51] - javacard/security/CryptoException/algorithmCheck(BS)V
0x498802: RETURN - returns: V0x0
LIB[7] - 0x4987f0: NEW [0x1c 0x18]
total number of effective EEPROM writing = 0xbc
total number of requested atomic update = 0x1e6
number EEPROM writing saved thanks NVL = 0x4f6
Exception: VM; SystemException; reason: 5
< INVALID exceptions java.lang for >INTP Exception jump to dispatch loop
total number of effective EEPROM writing = 0xbc
total number of requested atomic update = 0x1e6
number EEPROM writing saved thanks NVL = 0x4f6
By checking the source code of JCRE of the OS I’ve found that “reason 5” is No Resources. Checking available volatile and non volatile memory, it seems there is enough memory. From the dump I couldn’t figure out what was wrong. So no clue!
Next step to analyze applet bytecode. Fortunately Gemalto Developer Suite has utility called “Cap File Utility”. I dumped applet and searched the exact consequence of commands from dump of JCRE. After a while I found in the applet dump the following:
method_info[8] // @04b4= {
    // Some part skipped
    /*0f31*/ sand
    /*0f32*/ sadd
    /*0f33*/ s2b
    /*0f34*/ bastore
    /*0f35*/ L124: aload_0
    /*0f36*/ sconst_5
    /*0f37*/ sconst_0
    /*0f38*/ invokestatic 57
    /*0f3b*/ putfield_a 26
    /*0f3d*/ getfield_a_this 26
    /*0f3f*/ getfield_a_this 23
    /*0f41*/ sload 10
}

Pay attention to /*0f38*/ invokestatic 57. It is last call from the applet before switching to system libraries. So, it has to be something wrong with this call. But how to find what exactly it is calling. Here we have to check Component_Pool from the dump:
.Constant_Pool {
    // some part skipped
    /* 00e4, 57 */CONSTANT_StaticMethodRef : external: 0x84,0x1,0x0
    // some part skipped
}
So here it is – static method 57. It is referencing to external package. By checking ImportComponent I’ve found the right one. Here I have to mention that 0x84,0x1,0x00 means:
  • 0x84 – is 5th package in ImportComponent section due to numbering starts from 0x80
  • 0x1 – is the class number
  • 0x0 is method number
Here extract from applet dump:
.ImportComponent = {
    // some part skipped, it is 5th package due to 1st one has reference 0x80
    package_info = {
        minor_version : 2
        major_version : 1
        AID_length : 7
        AID : a0.00.00.00.62.02.01
    }
    // some part skipped }
Now we know what is AID of the imported package: a0.00.00.00.62.02.01. It is standard package javacardx.security. To figure out what is class 1 and method 0 we have to dump javacrdx.security.exp file. Below is extract from dump:
class_info { // javacardx/crypto/Cipher
    u1 token : 1 <== Class identification number
    u2 access_flags : 10000000001b
    u2 name_index : 57
    u2 export_supers_count : 1
    // some parts skipped
    export_methods {
        method_info { // getInstance
            u1 token : 0 <== Method identification number
            u2 access_flags : 11001b
            u2 name_index : 42
            u2 descriptor_index : 43
        }
    // some parts skipped
}
So now we know which method raises exception. It is getInstance() method of Cipher class. In the source code of the applet getInstance() method has called as follows:


myCipher = Cipher.getInstance( Cipher.ALG_DES_ECB_NOPAD, false );


According to specification JavaCard API:
getInstance
public static final Cipher getInstance(byte algorithm,
boolean externalAccess)
throws CryptoException
Creates a Cipher object instance of the selected algorithm.
Parameters:
algorithm - the desired Cipher algorithm. Valid codes listed in ALG_ .. constants above, for example, ALG_DES_CBC_NOPAD.
externalAccess - true indicates that the instance will be shared among multiple applet instances and that the Cipher instance will also be accessed (via a Shareable interface) when the owner of the Cipher instance is not the currently selected applet. If true the implementation must not allocate CLEAR_ON_DESELECT transient space for internal data.
Returns:
the Cipher object instance of the requested algorithm
Throws:
CryptoException - with the following reason codes:
  • CryptoException.NO_SUCH_ALGORITHM if the requested algorithm is not supported or shared access mode is not supported.

Et Voila! Issue is in externalAccess. We have to set it true, as STK applets are not explicitly selected applets by SELECT APPLICATION. They are triggered by SIM Toolkit Events.
So, changing to true externalAccess parameter has solved issue.

5 Jan 2011

LTE Basics

I’ve found the good introduction to LTE from network perspective. Enjoy.

Link to presentations

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

How mobile phone and SIM card setup connection or why sometime mobile phone rejects SIM Card?

A little bit theory
First of all SIM Card is particular application of SmartCard usage hence low level part specified by series of ISO7816 standards. ISO7816-3 standard specifies the following procedure to initiate interaction between card and Interface Device:
  1. Cold Reset (RST)
  2. SIM Card answers ATR (Answer-to-Reset)
  3. PPS negotiation
  4. Data exchange
Let's review each point one by one:
Cold Reset
Cold Reset is sending electrical reset signal to contact C2:

Above picture is showing SIM Card with USB interface which specifies additional contacts like C4, C8, C6 which are not part of ISO standard.
Answer-to-Reset (ATR)
To reset signal SIM card answers sequence of bytes and it’s structure is the following:

The aim of the ATR is declaring to the mobile phone card capabilities.The connection parameters supported by card has been specified in TA1:
TA1 encodes the indicated value of the clock rate conversion integer (Fi), the indicated value of the baud rate adjustment integer (Di) and the maximum value of the frequency supported by the card (f(max.)).
PPS negotiation
For exchanging information, the card and the handset shall agree on transmission protocol and values of transmission parameters. This process called PPS (Protocol and Parameters Selection) negotiation. After that all information exchange has to follow agreed parameters.
All these parameters based on the nominal duration of one moment of the electrical circuit I/O is named “elementary time unit” and denoted etu:


The delay between the leading edges of two consecutive characters shall be at least 12 etu, i.e. the duration of one character, (10±0,2) etu, followed by a guardtime (GT).
The following figure describes it graphically:


Let’s take an example of ATR : 3B9E96801FC78031E073FE211B66D0007A008000FA
Here TA1 byte is 96. Below the trace taken using ContactLAB tracer between mobile phone and SIM Card:
PPS2
As you can see as the result of PPS negotiation mobile phone and card have agreed to the value 96 and frequency is f = 3.84 MHz.
Based on these values we can determine F and D values from the tables provided in ISO7816-3 standard:
Table 7 — Fi and f (max.)
Bits 8 to 5 0000 0001 0010 0011 0100 0101 0110 0111
Fi 372 372 558 744 1116 1488 1860 RFU
f (max.) MHz 4 5 6 8 12 16 20 -

Bits 8 to 5 1000 1001 1010 1011 1100 1101 1110 1111
Fi RFU 512 768 1024 1536 2048 RFU RFU
f (max.) MHz - 5 7,5 10 15 20 - -
Table 8 — Di
Bits 4 to 1 0000 0001 0010 0011 0100 0101 0110 0111
Di RFU 1 2 4 8 16 32 64
Bits 4 to 1 1000 1001 1010 1011 1100 1101 1110 1111
Di 12 20 RFU RFU RFU RFU RFU RFU
As our PPS is 96 we have to split it to MSB and LSB:
  • 9 = b1001 –> Fi = 512 (from the Table 7)
  • 6 = b0110 –> Di = 32 (from the Table 8)
Based on above information we can calculate etu for our case:
image
The minimum delay between two characters has to be 12 etu i.e.:
image
Mobile phone rejects SIM Card
Time to time you have messages like “Insert SIM Card” or “SIM Card failures” even in case of SIM Card is working on another handset. After we knows the theory we can analyze the reasons. Of course it requires some tracer equipment which is able to show precise timing of signals. Personally I am using Micropross or ContactLAB tracers depending on which one is available in my team right now. :)
The principle is pretty easy. You have to check timings of signals in two directions: Mobile phone –> SIM Card and SIM Card –> Mobile phone.
Let’s take an example:
Mobile phone –> SIM Card
Below the trace for APDU in direction Mobile phone –> SIM Card:
Mobile-Card
As you remember “The delay between the leading edges of two consecutive characters shall be at least 12 etu”. In our case 12 etu is 50.04 µS. Now pay attention to the time between 2 cursors (red and blue one). It is 55.150 µS i.e. everything is working well.
You can analyze the response of the card in the same manner and check time. If it is less than 12 etu it means issue on card side which is not respecting ISO standard and vice versa if timing is wrong from mobile phone to the SIM Card issue is in mobile phone.
Et Voila!

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.

Emacs ELPA and Wanderlust

After installation of Wanderlust in Emacs I’ve recognized that package.el has stopped working with message:

Symbol’s function definition is void: mailcap-parse-mailcaps

I did some investigation and figured out that it is conflict between mailcap.el in FLIM package and mailcap.el in Gnus. The first one is not defining mailcap-parse-mailcaps function.

Quick fix is loading mailcap.el from Gnus manually before FLIM loading:

(load-file "C:/emacs/emacs-24.0.50/lisp/gnus/mailcap.el")



I’m not sure that this is correct solution but it seems work.