SetIncomingAndReceive and setOutgoing

I have an applet works very smooth on JCOP card (T=1). Recently, I am trying to put this applet into Oberthur CosmopolIC Lite V1 and Gemplus GemXpresso Pro card (both T=1), and get very strange behavior on these 2 card. After my diagnosis, I found out the return code of setIncomingAndReceive and setOutgoing are different on these 3 cards.
The logic of my applet is using setIncomingAndReceive and setOutgoing to define the lc and le. Thus, for an APDU case 2 command such as 00 86 00 00 08, the JCOP card will get lc=0 and le=8, Oberthur card will get lc=8 and le=8, and Gemplus card will get lc=8 and le=0. Anyone know the correct behavior of these 2 methods? Or I should not use these 2 methods to define the lc and le?
A sample code can reproduce this problem is listed below for your reference, any comment will be appreciated!
package test;
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: </p>
* @author unascribed
* @version 1.0
import javacard.framework.*;
import javacard.security.*;
public class test extends Applet {
// Class instruction type (CLA)
static final byte TEST_CLA = (byte)0x00;
// Instruction (INS)
static final byte CASE2_TEST = (byte)0x86;
// SW
static final short SW_ERROR_1 = (short)0x6601;
static final short SW_ERROR_2 = (short)0x6602;
static final short SW_ERROR_3 = (short)0x6603;
static final short SW_ERROR_4 = (short)0x6604;
static final short SW_LE_NOT_8 = (short)0x6605;
static final short SW_OK = (short)0x6600;
// index of sys[]
static final short LC = (byte)0;
static final short LE = (byte)1;
static final short LA = (byte)2;
// transient objects
private short[] sys = JCSystem.makeTransientShortArray( (short)14, JCSystem.CLEAR_ON_DESELECT );
protected test( byte[] buffer, short offset, byte length ) {
register();
public static void install( byte[] bArray, short bOffset, byte bLength ) {
new test( bArray, bOffset, bLength );
public boolean select() {
return true;
public void deselect() {
public void process( APDU apdu ) {
byte[] apdu_buffer = apdu.getBuffer();
sys[ LC ] = apdu.setIncomingAndReceive();
if( selectingApplet() )
return;
if( apdu_buffer[ ISO7816.OFFSET_CLA ] != TEST_CLA )
ISOException.throwIt( ISO7816.SW_CLA_NOT_SUPPORTED );
switch( apdu_buffer[ ISO7816.OFFSET_INS ] ) {
case CASE2_TEST:
Case2( apdu, (short)0, (short)8 );
return;
default:
ISOException.throwIt( ISO7816.SW_INS_NOT_SUPPORTED );
private void processCase2( short lc, short le ) {
ISOException.throwIt( (short) (Util.makeShort( (byte)sys[LC], (byte)sys [LE])));
// if( sys[ LC ] != 0 )
// ISOException.throwIt( SW_ERROR_1 );
// ISOException.throwIt( (short) (sys[ LC ]) );
if( _le == (short)0 )
ISOException.throwIt( SW_ERROR_2 );
if( (_lc > (short)0) && ( sys[ LC ] != _lc ) )
ISOException.throwIt( SW_ERROR_3 );
if( (_le > (short)0) && ( sys[ LE ] != _le ) )
ISOException.throwIt( (short) (sys[ LE ]) );
// ISOException.throwIt( SW_ERROR_4 );
if( sys[ LC ] != 0 )
// ISOException.throwIt( SW_ERROR_1 );
ISOException.throwIt( (short) (sys[ LC ]) );
private void Case2( APDU apdu, short lc, short le ) {
byte[] buffer = apdu.getBuffer();
sys[ LE ] = apdu.setOutgoing();
apdu.setOutgoingLength( (short)8 );//sys[ LE ] );
processCase2( lc, le );
Util.setShort( buffer, (short)0, (short)200 );
apdu.sendBytes( (short)0, (short)8 );

This response involves off-card and on-card answers !
--------------Off card
What if the Le was 10H and middeware was expecting 20H ? I leave it up to the middleware to check the results.
I've run into this where the card specifications changed and the middleware was "hard coded" to process the Le of a certain value. This ultimately crashed the middleware when the card spec changed. The proper design would have been for the middleware to CHECK the Le and process that amount of data.
--------On card
You might have an on-card design that was expecting to return data but wanted to make sure the Le was the proper size for the results.see setOutgoingLength()

Similar Messages

  • Detect SELECT APDU

    Hi everyone
    I'm writing an applet (Java Card 2.1.1) and in the process method I'm trying to detect the SELECT APDU command, but it's not working. I send a SELECT APDU to my applet, it throws a SW_CLA_NOT_SUPPORTED exception, and it is selected. Ok, the command ends up doing what it is supposed to do, but my applet throws an exception, and it shouldn't.
    Here's my code:
    public void process(APDU apdu) throws ISOException {
      byte[] buffer = apdu.getBuffer();
      byte cla  = buffer[ISO7816.OFFSET_CLA];
      byte ins = buffer[ISO7816.OFFSET_INS];
      if (cla == CLA_FUNCIONARIO) {
          try {
              switch (ins) {
                  // all my cases
                  default:
                      ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
          catch (UserException e) {
              ISOException.throwIt(e.getReason());
      else if (selectingApplet()) {
          return;
      else {
          byte tamanho_lido = (byte) apdu.setIncomingAndReceive();
          apdu.setOutgoing();
          apdu.setOutgoingLength((short) (tamanho_lido + 4));
          apdu.sendBytes((short) 0, (short) 4);
          apdu.sendBytes(ISO7816.OFFSET_CDATA, tamanho_lido);
          ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
    }First of all, I don't know what exactly does the method selectingApplet - in several source codes I've seen around, the verification for the SELECT APDU is done like this:
    (cla == ISO7816.CLA_ISO7816 && ins == ISO7816.INS_SELECT)But, there are some sample codes (like the JavaPurse on JCDK 2.1.1) that prove these two ways of checking the SELECT APDU is not equivalent. So, what's the difference between using the selectingApplet method and using the constants on the ISO7816 interface? Should I use both ways? Only one of them???
    The big problem is what is actually happening to my card. As it can be seen in the code above, if the applet is about to throw an SW_CLA_NOT_SUPPORTED exception, it writes the whole command that it received, so I can see what got there (sort of a System.out.println debugging). And here's what happens: everytime I send the command 0x00 0xA4 0x04 0x00 0x06 0x01 0x02 0x03 0x04 0x05 0x06 0x00, it returns 0x00 0xC0 0x00 0x00 as the response data and 0x6E00 as the status word!!! I googled and I found that C0 is the INS byte of the GET RESPONSE command. What is this command? It's not documented on the GlobalPlatform 2.0.1' specification. And why the hell my applet says it received this command when I send it a SELECT APDU?
    Any answer would be valuable :)
    Thanks!

    You are in the ISO7816 T=0 protocol. The 00CO000000 command is issued to receive the response to the previous SELECT command. You are not returning any data to the SELECT command, but the terminal side seems to insist on getting one.
    The GetResponse command should not be passed to the Applet by your card operating system, I consider this a bug.
    If you return data when selectingApplet() returns true, then you probably will not have any problem.

  • Getting rid of 6CXX responses.

    Hello,
    while trying to mimic an older card with a JavaCard applet, I've run into an annoying issue. When reading a record of size XX:
    - card A (old card) replies with 61XX, and the host software does the obvious.
    - card B (JavaCard) replies with 6CXX, and the host software barfs.
    I don't want to argue what is the most correct solution (what would be the host software re-issuing the command with correct Le) but I'd like to know if/how it is possible to enforce a specific response from JavaCard side, as my idea is to mimic an existing card as closely as possible.
    The card is an JTOP one. I've digged through the JC2.2.2 documentation of javacard.framework.APDU and I don't really see hot this could be done differently. Playing around with different setOutgoing* combinations does not seem to affect it either.
    Any hints?

    Answering my own question for those who might stumble upon it.
    Say I have commands 00 12 00 00 00 and 00 12 00 00 64 and 0A bytes of data to send back (all numbers are hex).
    This is a case 2 APDU, thus P3 is supposed to be Le, not Lc, with the Le semantics as described in ISO (00 = "all data available up to 256"). I would like to process Le to send different SW-s with the data if necessary (like 6282 if called with the second command, where 0A < 64).
    Calling setIncomingAndReceive is thus not supposed to be called when implementing this command, as there is not supposed to be any input from the host (case 2)
    Calling setOutgoing* will result in an otherwise proper command-cycle with P3=00, but with 6CXX instead of 61XX.
    Thus it is needed to "eat away" the Le byte as empty (zero) Lc with setIncomingAndReceive if P3 == 00, after what setOutgoing will not have a reference value for the expected Le and setOutgoing* will result in 61XX response in T=0 mode (and of course, proper functioning in T=1 as well).
    Probably obvious, but made me wonder for a while.

  • RSA and Cyberflex

    hi,
    Someone know if there is some problem with RSA and the card "Cyberflex 64 ko"? because when I try to use RSA 1024 bit with this card, it return 6F00.
    I think the problem is on this line:
    KeyPair pairDeCle = new KeyPair(KeyPair.ALG_RSA, KeyBuilder.LENGTH_RSA_1024);The same applet, (same .cap) works with my other card. (In the card specification they say we can use the card with RSA 1024 or 2048 bit)
    regards
    nico

    my applet: (it is the same code of the post "RSA && contactless" with try/catch in addition)
    package fr.moneo_RSA_Biometrie;
    import org.javacardforum.javacard.biometry.SharedBioTemplate;
    //import fr.alex.biometry.SharedBioTemplate;
    import javacard.framework.AID;
    import javacard.framework.APDU;
    import javacard.framework.Applet;
    import javacard.framework.ISOException;
    import javacard.framework.ISO7816;
    import javacard.framework.JCSystem;
    import javacard.framework.OwnerPIN;
    import javacard.security.DESKey;
    import javacard.security.CryptoException;
    import javacard.security.KeyBuilder;
    import javacard.security.KeyPair;
    import javacard.security.RSAPrivateKey;
    import javacard.security.RSAPublicKey;
    import javacardx.crypto.Cipher;
         public class Application_moneo_RSA_biometrie extends Applet {
                final byte CLA_MONAPPLET = (byte) 0xB0;
                final byte INS_INCREMENTER_COMPTEUR = 0x00;
                final byte INS_DECREMENTER_COMPTEUR = 0x01;
                final byte INS_INTERROGER_COMPTEUR = 0x02;
                final byte INS_INITIALISER_COMPTEUR = 0x03;
                final byte INS_SAISIR_CODE = 0x04;
                final byte INS_CRYPTO = 0x05;
                final byte INS_INIT = 0x06;
                private boolean flagCrypto = false;      
                Cipher ecipher;
                   private DESKey key;
                   KeyPair pairDeCle;
                public OwnerPIN pin;
                private byte[] pinBon = {0x31,0x30,0x30,0x30};           
                private RSAPublicKey clePublic;
                private RSAPrivateKey clePrive;
                private byte[] Crypto;
                private byte compteur;           
                       private AID bioServerAID;
                       SharedBioTemplate bioImpl;
                       private static final byte[] BIO_SERVER_AID = {(byte)0x01, (byte)0x02, (byte)0x03,(byte)0x04, (byte)0x05, (byte)0x06,(byte)0x07, (byte)0x08, (byte)0x07,(byte)0x06, (byte)0x05, (byte)0x04};
              public Application_moneo_RSA_biometrie() {
                   compteur = 5;
                   pin = new OwnerPIN((byte)2, (byte)4);          
                   pin.update(pinBon, (short)0, (byte)4);
              public static void install(byte bArray[], short bOffset, byte bLength)
                   throws ISOException {
                   new Application_moneo_RSA_biometrie().register();
              public void process(APDU apdu) throws ISOException {
                   byte[] buffer = apdu.getBuffer();
                   if (this.selectingApplet()){
                        initialisation();     
                           bioServerAID = JCSystem.lookupAID(BIO_SERVER_AID,(short)0,(byte)BIO_SERVER_AID.length);               
                                    bioImpl = (SharedBioTemplate) JCSystem.getAppletShareableInterfaceObject(bioServerAID,(byte)0);                                         
                                    apdu.setOutgoing();
                        apdu.setOutgoingLength((short)Crypto.length);
                        apdu.sendBytesLong(Crypto,(short) 0, (short) Crypto.length);
                            return;
                   if (buffer[ISO7816.OFFSET_CLA] != CLA_MONAPPLET) {
                        ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
                   switch (buffer[ISO7816.OFFSET_INS]) {
                   case INS_INIT:
                        break;
                   case INS_SAISIR_CODE:
                        byte byteRead = (byte) apdu.setIncomingAndReceive();
                        byte[] partieAdecrypter = RecupererPartieDeAPDU(apdu.getBuffer(), (short)5, (short)byteRead);          
                        byte[] derypt = decrypter(partieAdecrypter);
                        short u =0;
                        for(short i = 5; i<9; i++){
                        buffer[i] = derypt[u];
                        u++;
                        short result = bioImpl.match(buffer,(short) 5, (short) 4);
                        if (!bioImpl.isValidated()){
                             ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
                        break;
                   case INS_INCREMENTER_COMPTEUR:
                             if (bioImpl.isValidated())
                             compteur++;
                             else {
                                  ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
                             break;
                   case INS_DECREMENTER_COMPTEUR:
                             if (bioImpl.isValidated())
                             compteur--;
                             else {
                                  ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
                             break;
                   case INS_INTERROGER_COMPTEUR:
                             if (bioImpl.isValidated()){
                             byte[] valeur = new byte [2];
                             valeur[0] = compteur;
                             apdu.setOutgoing();
                             apdu.setOutgoingLength((short)valeur.length);
                             apdu.sendBytesLong(valeur,(short) 0, (short) valeur.length);                    
                             }else {
                                  ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
                             break;
                   case INS_INITIALISER_COMPTEUR:
                             if (bioImpl.isValidated())
                             apdu.setIncomingAndReceive();
                             compteur = buffer[ISO7816.OFFSET_CDATA];
                             else {
                                  ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
                             break;
                   default:
                             ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
              public byte[] RecupererPartieDeAPDU(byte[] tableauReference, short offset, short length){
                   byte[] copieTableau = new byte[length];
                   short u =0;
                   for (short i= offset; i<(short)(offset+length); i++){
                        copieTableau[u]=tableauReference;
                        u = (short)(u + 1);
                   return copieTableau;     
         public void initialisation(){
              try{
              pairDeCle = new KeyPair(KeyPair.ALG_RSA, KeyBuilder.LENGTH_RSA_1024);
              } catch (CryptoException e){
                   ISOException.throwIt((short) e.ILLEGAL_USE);
                   ISOException.throwIt((short) e.ILLEGAL_VALUE);
                   ISOException.throwIt((short) e.INVALID_INIT);
                   ISOException.throwIt((short) e.NO_SUCH_ALGORITHM);
                   ISOException.throwIt((short) e.UNINITIALIZED_KEY);
              } catch (Exception e){
                   ISOException.throwIt((short)4000);
              pairDeCle.genKeyPair();
              clePublic = (RSAPublicKey) pairDeCle.getPublic();
              clePrive = (RSAPrivateKey) pairDeCle.getPrivate();
              byte[] buffer1 = new byte[1024];
              short tailleExponent = clePublic.getExponent(buffer1, (short)0);
              byte[] exponent = new byte[tailleExponent];
              clePublic.getExponent(exponent, (short)0);
              byte[] buffer2 = new byte[512];
              short tailleModulus = clePublic.getModulus(buffer2, (short)0);
              byte[] modulus = new byte[tailleModulus];
              clePublic.getModulus(modulus, (short)0);
              byte[] positif = new byte[1];
              positif[0] = (byte)0x00;
              byte[] moduluspositif = concatener(positif, modulus, (short)0, (short)modulus.length);
              byte[] sizeExp = new byte[1];
              byte[] sizemodulus = new byte[1];
              sizeExp[0] = (byte)exponent.length;
              sizemodulus[0] = (byte)moduluspositif.length;
              byte[] tailleAndExp = concatener(sizeExp, exponent, (short)0, (short)exponent.length);
              byte[] tailleAndmodulus = concatener(sizemodulus, moduluspositif, (short)0, (short)moduluspositif.length);
              Crypto = concatener(tailleAndExp, tailleAndmodulus, (short)0, (short)tailleAndmodulus.length);
         public byte[] concatener(byte[] tableRef, byte[] tabACopier, short offset, short lenght){
              byte [] newTab = new byte[(short)(tableRef.length + lenght)];
              for(short o = 0; o < (short)tableRef.length; o++){
                   newTab[o] = tableRef[o];
              short u = 0;
              for(short i = (short) tableRef.length; i < (short)(tableRef.length + lenght); i++){               
                   newTab[i] = tabACopier;
                   u = (short)(u + 1 + offset);
              return newTab;          
         public byte[] recuperDonnee(APDU apdu){
              byte[] buf = apdu.getBuffer();
              short lc = apdu.setIncomingAndReceive();
              byte[] data = new byte[lc];
              short u =0;
              for(short i = 5; i<(short)(5+lc);i++){
                   data[u] = buf;
                   u = (short) (u+1);     
              return data;
         public byte[] decrypter(byte[] data ){
              Cipher cipher = Cipher.getInstance(Cipher.ALG_RSA_PKCS1, false);
              cipher.init(clePrive,Cipher.MODE_DECRYPT);     
              byte[] donneDecrypt = new byte[(short)data.length];
              cipher.doFinal(data, (short)0, (short)data.length, donneDecrypt, (short)0);
              return donneDecrypt;

  • Some questions about javacard 2.1.1 and smartcardio

    Hello i have some question about java card 2.1.1 and the smartcardio package.
    1.) I want to sign a message with the Signature.ALG_RSA_SHA_PKCS1 algorithm. I use the following code in the applet to sign the message:
    final static byte P1_CREATION_MODE = (byte) 0x01;
    final static byte INS_SIGN_MODE = (byte) 0x60;
    final static byte SmartCard_CLA = (byte) 0xB0;
    private void signMessage(APDU apdu) {
            byte[] buffer = apdu.getBuffer();
            byte byteRead = (byte) (apdu.setIncomingAndReceive());
            signature.init(privateKey, Signature.MODE_SIGN);
            short length = signature.sign(buffer, ISO7816.OFFSET_CDATA, byteRead, buffer, (short) 0);
            apdu.setOutgoingLength((short) length);
            apdu.sendBytesLong(buffer, (short) ISO7816.OFFSET_CDATA, (short) length);
            apdu.setOutgoing();
        }On the host side I use the following code to connect to the card and to send the sign apdu:
    if (TerminalFactory.getDefault().terminals().list().size() == 0) {
                LOGGER.log(Level.SEVERE, "No reader present");
                throw new NoSuchCardReader();
            /* Select the first terminal*/
            CardTerminal terminal = TerminalFactory.getDefault().terminals().list().get(0);
            /* Is a card present? */
            if (!terminal.isCardPresent()) {
                LOGGER.log(Level.SEVERE, "No Card present!");
                throw new NoSuchCard();
            /* Set the card protocol */
         Card card = terminal.connect("*");
            ATR atr = card.getATR();
            LOGGER.fine(getHexString(atr.getBytes()));
            LOGGER.fine(getHexString(atr.getHistoricalBytes()));
            CardChannel channel = card.getBasicChannel();
            CommandAPDU cmd = new CommandAPDU((byte) 0xb0, (byte) 0x60, (byte) 0x01, (byte) 0x00, new String("datadatdatadata").getBytes(), (byte) 0x40);
         ResponseAPDU response = channel.transmit(cmd);
            card.disconnect(false);But this does not work and i got the following error
    javax.smartcardio.CardException: sun.security.smartcardio.PCSCException: Unknown error 0x8010002f
            at sun.security.smartcardio.ChannelImpl.doTransmit(ChannelImpl.java:202)
            at sun.security.smartcardio.ChannelImpl.transmit(ChannelImpl.java:73)
            at de.upb.client.smartmeter.SmartMeter.initSmartCardApplet(SmartMeter.java:114)
            at de.upb.client.smartmeter.SmartMeterApplikation.main(SmartMeterApplikation.java:39)
    Caused by: sun.security.smartcardio.PCSCException: Unknown error 0x8010002f
            at sun.security.smartcardio.PCSC.SCardTransmit(Native Method)
            at sun.security.smartcardio.ChannelImpl.doTransmit(ChannelImpl.java:171)
            ... 3 more2.) 3Des encryption
    I want to use the 3Des algorithm to encrypt my data. I use
    keyDES = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES,
                        KeyBuilder.LENGTH_DES3_2KEY, false);
    cipherDES = Cipher.getInstance(Cipher.ALG_DES_CBC_ISO9797_M2, false);But i do not know what is the aquivalent on the host side??
    3.) Another problem is that i am not able to send the modulus of a public key from the host applikation to the smard card
    new CommandAPDU((byte) 0xb0, (byte) 0x20, (byte) 0x01, (byte) 0x00, modulus.toByteArray()); // create the apdu
    // the method in the applet
    private void setServerKeyMod(APDU apdu) {
            byte[] buffer = apdu.getBuffer();
            try {
                byte byteRead = (byte) (apdu.setIncomingAndReceive());
                short off = ISO7816.OFFSET_CDATA;
                // strip of any integer padding
                if (buffer[off] == 0) {
                    off++;
                    byteRead--;
                publicKeyServer.setModulus(buffer, off, byteRead);
            } catch (APDUException ex) {
                ISOException.throwIt((short) (SW_APDU_EXCEPTION + ex.getReason()));
        }The error code is 6700
    4.) My last problem ist, that i am not able to use a value bigger than 0x7F as the ne field in the apducommand, because i get the following error
    CommandAPDU((byte) 0xb0, (byte) 0x60, (byte) 0x01, (byte) 0x00, data, (byte) 0xff);
    java.lang.IllegalArgumentException: ne must not be negative
            at javax.smartcardio.CommandAPDU.<init>(CommandAPDU.java:371)
            at javax.smartcardio.CommandAPDU.<init>(CommandAPDU.java:252)I thought that it this should be possible in order to use all the bytes of the response apdu.
    If you need more code to help please let me know.
    Cheers
    Edited by: 858145 on 06.07.2011 08:23

    2) What is PKCS? what is the difference between
    PKCS#11 and PKCS#15??PKCS is the abbreviation of "Public-Key Cryptography Standards"
    PKCS #11: Cryptographic Token Interface Standard
    See http://www.rsasecurity.com/rsalabs/node.asp?id=2133
    PKCS #15: Cryptographic Token Information Format Standard
    http://www.rsasecurity.com/rsalabs/node.asp?id=2141
    If you want to use yor smartcard as secure token it doesn't have to be a JavaCard.
    BTW: I don't remember a way to access PKCS#15 tokens on a JavaCard from within an oncard JavaCard program. If you want to use keys in your oncard program, you have to transfer it onto the card or generate it oncard and export the public key by your own oncard/offcard code.
    Jan

  • Access Terminal and select applet

    Hi people,
    I have a question about to run the aplet in a javacard. Is there any code or other useful material about getting terminal and select applet and run the methods of the apllet in a programmable manner? Thanks for your interest...
    Edited by: POLAT on Mar 16, 2009 7:41 PM

    Honestly I haven't figured out how to pass a pin when selecting the applet, however at the minute I have a way around it:
    you will see in teh code below, I have hardcoded a default pin and I have a pin update method that can be called via a apdu,
    NOTE this example works with the code above:
    *Applet ID 41 63 63 6F 75 6E 74 41 70 70 6C
    public class AccountApplet extends Applet {
         final static byte ACCOUNT_CLA = (byte)0xB0;
         final static byte VERIFY = (byte) 0x20;
         final static byte CREDIT = (byte) 0x30;
         final static byte DEBIT = (byte) 0x40;
         final static byte GET_BALANCE = (byte) 0x50;
         final static byte UPDATE_PIN = (byte) 0x60;
         final static short MAX_BALANCE = 10000;
         final static byte MAX_TRANSACTION_AMOUNT = 100;
         final static byte PIN_TRY_LIMIT =(byte)0x03;
         final static byte MAX_PIN_SIZE =(byte)0x08;
         // Applet-specific status words:
         OwnerPIN pin;
         short balance = 109; // Starting balance of decimal 109 is 6D in hex
         public static void install(byte[] bArray, short bOffset, byte bLength) {
                        new AccountApplet(bArray, (short) (bOffset + 1), bArray[bOffset]);
         private AccountApplet(byte[] bArray, short bOffset, byte bLength){
              pin = new OwnerPIN(PIN_TRY_LIMIT, MAX_PIN_SIZE);
              // bArray contains the default PIN initialization value (12345)
              bArray[0] = 01;
              bArray[1] = 02;
              bArray[2] = 03;
              bArray[3] = 04;
              bArray[4] = 05;
              bOffset = 0;
              bLength = 5;
              pin.update(bArray, bOffset, bLength);
              register();
         public boolean select() {
         if (pin.getTriesRemaining() == 0)
                   return false;
              return true;
    public void deselect() {
         pin.reset();
         public void process(APDU apdu) {
    byte[] buffer = apdu.getBuffer();
              if (selectingApplet())
                   return;
              if (buffer[ISO7816.OFFSET_CLA] != ACCOUNT_CLA)
                   ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
              switch (buffer[ISO7816.OFFSET_INS]) {
              case GET_BALANCE:          getBalance(apdu);      return;
              case DEBIT:                    debit(apdu);             return;
              case CREDIT:               credit(apdu);           return;
              case VERIFY:               verify(apdu);          return;
              case UPDATE_PIN:          updatePin(apdu);     return;
              default:                    ISOException.throwIt
              (ISO7816.SW_INS_NOT_SUPPORTED);
    private void credit(APDU apdu) {
              if (!pin.isValidated())
                   ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
              byte[] buffer = apdu.getBuffer();
         byte numBytes = buffer[ISO7816.OFFSET_LC];
              byte byteRead = (byte)(apdu.setIncomingAndReceive());
              if (( numBytes != 1 ) || (byteRead != 1))
                   ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
              byte creditAmount = buffer[ISO7816.OFFSET_CDATA];
              if (( creditAmount > MAX_TRANSACTION_AMOUNT)
                        || ( creditAmount < 0 ))
                   ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
              if ((short)( balance + creditAmount)  > MAX_BALANCE)
                   ISOException.throwIt(SW_EXCEED_MAXIMUM_BALANCE);
              balance = (short)(balance + creditAmount);
              return;
         private void updatePin(APDU apdu) {
              if (! pin.isValidated())
                   ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
              byte[] buffer = apdu.getBuffer();
              byte numBytes = buffer[ISO7816.OFFSET_LC];
              byte byteRead = (byte)(apdu.setIncomingAndReceive());
                   if (byteRead != numBytes) {
                   ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
                   if ( numBytes > 8 )
                   ISOException.throwIt(SW_PIN_TO_LONG);
              if ( numBytes < 4 )
                   ISOException.throwIt(SW_PIN_TO_SHORT);     
              short offset_cdata = 05;          
              pin.update(buffer, offset_cdata, numBytes);
              pin.resetAndUnblock();
         private void debit(APDU apdu) {
              if (! pin.isValidated())
                   ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
              byte[] buffer = apdu.getBuffer();
              byte numBytes = (byte)(buffer[ISO7816.OFFSET_LC]);
         byte byteRead = (byte)(apdu.setIncomingAndReceive());
              if (( numBytes != 1 ) || (byteRead != 1))
                   ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
         byte debitAmount = buffer[ISO7816.OFFSET_CDATA];
              if (( debitAmount > MAX_TRANSACTION_AMOUNT)
                        ||  ( debitAmount < 0 ))
                   ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
              if ((short)( balance - debitAmount ) < (short)0)
                   ISOException.throwIt(SW_NEGATIVE_BALANCE);
              balance = (short) (balance - debitAmount);
         }      private void getBalance(APDU apdu) {
              byte[] buffer = apdu.getBuffer();
              short le = apdu.setOutgoing();
              apdu.setOutgoingLength((byte)2);
         Util.setShort(buffer, (short)0, balance);
              apdu.sendBytes((short)0, (short)2);
          * verification method to verify the PIN
         private void verify(APDU apdu) {
              byte[] buffer = apdu.getBuffer();
              byte byteRead = (byte)(apdu.setIncomingAndReceive());
              if (pin.check(buffer, ISO7816.OFFSET_CDATA,byteRead)
                        == false)
                   ISOException.throwIt(SW_VERIFICATION_FAILED);
         } // end of verify method
    } // end of class Account

  • Apdu.setIncomingAndReceive() ??

    In order to receive the whole apdu commmand send to the card, we must implement apdu.setIncomingAndReceive(), right? But when i receive command like [00 A0 00 00 50] for the below method indicate that i will get 0x50(80 bytes) data out. But the apdu.setIncomingAndReceive() will wait the coming 80 bytes data but there is not any data sending in as i am requesting to get 80 bytes data. As a result a i will get a error msg of time out error. So the program will stuck here and will not proceed to send the data out. How am i going to solve this? Is there and receive method to just receive the first 5 bytes of apdu command? hope u can understand my question. Thank you!
    private void getData(APDU apdu)
    byte[] buffer = apdu.getBuffer();
    short length = apdu.setIncomingAndReceive();
    Util.arrayCopyNonAtomic(Data ,0 , buffer,(short) 5, buffer[5] );
    apdu.setOutgoingAndSend((short) 5, buffer[5]);
    }

    Like he said the first 5 bytes should be read into the buffer automatically when the process() method receives an APDU. If you only sent 5 bytes then you have nothing left to receive so calling setIncomingAndReceive might cause it to hang. Why you would send an APDU with a non-zero data length setting if you aren't sending data might be another question.
    If you are in fact sending more data you can do something like the following:
         short bytesLeft = (short) (buffer[ISO7816.OFFSET_LC] & 0x00FF);
         short readCount = apdu.setIncomingAndReceive();
         while ( bytesLeft > 0){
              // process bytes in buffer[5] to buffer[readCount+4];
              bytesLeft -= readCount;
              readCount = apdu.receiveBytes ( ISO7816.OFFSET_CDATA );
         }

  • Internal mechanism about setOutgoing(), setOutgoingLength(), sendBytes()?

    Title: Who knows internal mechanism about setOutgoing(), setOutgoingLength(), and sendBytes()?
    The thing I want my applet to do is sending a 160-byte array out. The environment is JCOP 2.2 on card and JPCSC off card, and the code (prefixed with line number) is as follow:
    1       byte apduBuffer[] = apdu.getBuffer();
    2       // set the data transfer direction to outbound
    3       apdu.setOutgoing();
    4       // inform the host of the number of bytes in the data field
    5       apdu.setOutgoingLength((short)160);
    6       //copy data from an internal array to apduBuffer[]
    7       for((short)i=0; i<(short)160; i++)
    8       {
    9           apduBuffer[i] = Bob_PubSpecData;
    10 }
    11 // at offset 0 send x byte of data in the buffer
    12 apdu.sendBytes((short)0, (short)160);
    The array Bob_PubSpecData[160] has data as 385C...614A3C8B92D8.
    The ADPU message I received off card is 00300000A0385C...61, which has a header of 00300000A0 and data is 5-byte shorter than Bob_PubSpecData[160]. Strangely only 155-byte data but the Lc is still A0 (=160).
    (All the following tests are starting only from the above codes)
    Test(1): I changed 0 in 12th line to 5. ADPU message received off card is 385C...610000000000. Header is removed but the last 5 bytes are all filled by 0s.
    Test(2): I changed apduBuffer[i] in 9th line to apduBuffer[i+5], and got the same result as test(1).
    Test(3): I changed 160 in 5th line to 165, and got the same result as test(1).
    Who knows the internal mechanism of the setOutgoing(), setOutgoingLength(), and sendBytes()? I have the book of Java Card by Zhiqun Chen, but she didn't explain very clearly about these. I and my team member spent long time doing the various experiment today but still cannot get the correct result. Who can give us a hand?

    Very strange indeed.
    If I were you, I would perform the following tests:
    1. Change 160 to 4.
    2. Change 160 to 127.
    3. Place "apdu.setOutgoingLength((short)160)" right before apdu.sendBytes() (in 11th string).
    Indistinct ideas, but they may give some additional info...

  • A problem with Threads and loops.

    Hi, I have some code that needs to be constantly running, like while(true)
          //code here
    }However, the code just checks to see if the user has input anything (and then if the user has, it goes to do some other stuff) so I don't need it constantly running and hogging up 98% of the CPU. So I made my class (which has the method that needs to be looped, call it ClassA) implement Runnable. Then I just added the method which needed to be looped into the public void run()
    I have another class which creates an instance of the above class (call it ClassB), and the main(String[] args) is in there.
    public static void main(String[] args)
              ClassA test = new ClassA();
              Thread thread = new Thread(test.getInstanceOfClassA());
              thread.start();
              while(true)
                           //I do not know what to put here
                   try
                        thread.sleep(100);
                   catch(InterruptedException iex)
         }However, the thread only calls run() once,(duh...) but I can't think of away to get it to run - sleep - run -sleep forever. Can someone help me?

    Hi, I have some code that needs to be constantly
    running, like while(true)
    //code here
    }However, the code just checks to see if the user has
    input anything (and then if the user has, it goes to
    do some other stuff) so I don't need it constantly
    running and hogging up 98% of the CPU. Where does the user input come from. Are you reading from an InputStream? If so, then your loop will be blocked anyway when reading from the InputStream until data is available. During that time, the loop will not consume processor cycles.
    public static void main(String[] args)
              ClassA test = new ClassA();
    Thread thread = new Thread(test.getInstanceOfClassA());I have never seen this idiom. If ClassA instanceof Runnable, you simply write new Thread(test).
              thread.start();
              while(true)
    //I do not know what to put
    do not know what to put here
                   try
                        thread.sleep(100);
                   catch(InterruptedException iex)
         }However, the thread only calls run() once,(duh...)Yeah, why would you want to call it more than once given that you have an infinite loop in ClassA.run()?
    Harald.
    Java Text Crunching: http://www.ebi.ac.uk/Rebholz-srv/whatizit/software

  • A problem with Threads and MMapi

    I am tring to execute a class based on Game canvas.
    The problem begin when I try to Play both a MIDI tone and to run an infinit Thread loop.
    The MIDI tone "Stammers".
    How to over come the problem?
    Thanks in advance
    Kobi
    See Code example below:
    import java.io.IOException;
    import java.io.InputStream;
    import javax.microedition.lcdui.Graphics;
    import javax.microedition.lcdui.Image;
    import javax.microedition.lcdui.game.GameCanvas;
    import javax.microedition.media.Manager;
    import javax.microedition.media.MediaException;
    import javax.microedition.media.Player;
    public class MainScreenCanvas extends GameCanvas implements Runnable {
         private MainMIDlet parent;
         private boolean mTrucking = false;
         Image imgBackgound = null;
         int imgBackgoundX = 0, imgBackgoundY = 0;
         Player player;
         public MainScreenCanvas(MainMIDlet parent)
              super(true);
              this.parent = parent;
              try
                   imgBackgound = Image.createImage("/images/area03_bkg0.png");
                   imgBackgoundX = this.getWidth() - imgBackgound.getWidth();
                   imgBackgoundY = this.getHeight() - imgBackgound.getHeight();
              catch(Exception e)
                   System.out.println(e.getMessage());
          * starts thread
         public void start()
              mTrucking = true;
              Thread t = new Thread(this);
              t.start();
          * stops thread
         public void stop()
              mTrucking = false;
         public void play()
              try
                   InputStream is = getClass().getResourceAsStream("/sounds/scale.mid");
                   player = Manager.createPlayer(is, "audio/midi");
                   player.setLoopCount(-1);
                   player.prefetch();
                   player.start();
              catch(Exception e)
                   System.out.println(e.getMessage());
         public void run()
              Graphics g = getGraphics();
              play();
              while (true)
                   tick();
                   input();
                   render(g);
          * responsible for object movements
         private void tick()
          * response to key input
         private void input()
              int keyStates = getKeyStates();
              if ((keyStates & LEFT_PRESSED) != 0)
                   imgBackgoundX++;
                   if (imgBackgoundX > 0)
                        imgBackgoundX = 0;
              if ((keyStates & RIGHT_PRESSED) != 0)
                   imgBackgoundX--;
                   if (imgBackgoundX < this.getWidth() - imgBackgound.getWidth())
                        imgBackgoundX = this.getWidth() - imgBackgound.getWidth();
          * Responsible for the drawing
          * @param g
         private void render(Graphics g)
              g.drawImage(imgBackgound, imgBackgoundX, imgBackgoundY, Graphics.TOP | Graphics.LEFT);
              this.flushGraphics();
    }

    You can also try to provide a greater Priority to your player thread so that it gains the CPU time when ever it needs it and don't harm the playback.
    However a loop in a Thread and that to an infinite loop is one kind of very bad programming, 'cuz the loop eats up most of your CPU time which in turn adds up more delays of the execution of other tasks (just as in your case it is the playback). By witting codes bit efficiently and planning out the architectural execution flow of the app before start writing the code helps solve these kind of issues.
    You can go through [this simple tutorial|http://oreilly.com/catalog/expjava/excerpt/index.html] about Basics of Java and Threads to know more about threads.
    Regds,
    SD
    N.B. And yes there are more articles and tutorials available but much of them targets the Java SE / EE, but if you want to read them here is [another great one straight from SUN|http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html] .
    Edited by: find_suvro@SDN on 7 Nov, 2008 12:00 PM

  • Problem with Threads and a static variable

    I have a problem with the code below. I am yet to make sure that I understand the problem. Correct me if I am wrong please.
    Code functionality:
    A timer calls SetState every second. It sets the state and sets boolean variable "changed" to true. Then notifies a main process thread to check if the state changed to send a message.
    The problem as far I understand is:
    Assume the timer Thread calls SetState twice before the main process Thread runs. As a result, "changed" is set to true twice. However, since the main process is blocked twice during the two calls to SetState, when it runs it would have the two SetState timer threads blocked on its synchronized body. It will pass the first one, send the message and set "changed" to false since it was true. Now, it will pass the second thread, but here is the problem, "changed" is already set to false. As a result, it won't send the message even though it is supposed to.
    Would you please let me know if my understanding is correct? If so, what would you propose to resolve the problem? Should I call wait some other or should I notify in a different way?
    Thanks,
    B.D.
    Code:
    private static volatile boolean bChanged = false;
    private static Thread objMainProcess;
       protected static void Init(){
            objMainProcess = new Thread() {
                public void run() {
                    while( objMainProcess == Thread.currentThread() ) {
                       GetState();
            objMainProcess.setDaemon( true );
            objMainProcess.start();
        public static void initStatusTimer(){
            if(objTimer == null)
                 objTimer = new javax.swing.Timer( 1000, new java.awt.event.ActionListener(){
                    public void actionPerformed( java.awt.event.ActionEvent evt){
                              SetState();
        private static void SetState(){
            if( objMainProcess == null ) return;
            synchronized( objMainProcess ) {
                bChanged = true;
                try{
                    objMainProcess.notify();
                }catch( IllegalMonitorStateException e ) {}
        private static boolean GetState() {
            if( objMainProcess == null ) return false;
            synchronized( objMainProcess ) {
                if( bChanged) {
                    SendMessage();
                    bChanged = false;
                    return true;
                try {
                    objMainProcess.wait();
                }catch( InterruptedException e ) {}
                return false;
        }

    Thanks DrClap for your reply. Everything you said is right. It is not easy to make them alternate since SetState() could be called from different places where the state could be anything else but a status message. Like a GREETING message for example. It is a handshaking message but not a status message.
    Again as you said, There is a reason I can't call sendMessage() inside setState().
    The only way I was able to do it is by having a counter of the number of notifies that have been called. Every time notify() is called a counter is incremented. Now instead of just checking if "changed" flag is true, I also check if notify counter is greater than zero. If both true, I send the message. If "changed" flag is false, I check again if the notify counter is greater than zero, I send the message. This way it works, but it is kind of a patch than a good design fix. I am yet to find a good solution.
    Thanks,
    B.D.

  • Problem with Threads and "plase wait..."-Window

    Hi everyone,
    I have a problem that I'm not able to solve in any way... I have a time-consuming task (a file decryption) which I execute in a separate thread; I've used the SwingWorker class, like suggested by sun-tutorial, and it works right. The problem is that I have to wait that the decryption have finished before continuing with program-execution. Therefore I would like to display a "please wait"-window while the task runs. I've tryed all the possible ways I know but the problem is always the same: the waitWindow is displayed empty, the bounds are painted but the contents no; it's only painted when the decrypt-task has finished. Please help me, I have no more resources....
    decrypt-file code:
    public class DecryptFile {
      private String cryptedFileNameAndPath;
      private ByteArrayInputStream resultStream = null;
      // need for progress
      private int lengthOfTask;
      private int current = -1;
      private String statMessage;
      public DecryptFile(String encZipFileNameAndPath) {
        cryptedFileNameAndPath = encZipFileNameAndPath;
        //Compute length of task...
        // 0 for indeterminate
        lengthOfTask = 0;
      public ByteArrayInputStream getDecryptedInputStream() {
        return this.resultStream;
       * Called from ProgressBarDemo to start the task.
      public void go() {
        current = -1;
        final SwingWorker worker = new SwingWorker() {
          public Object construct() {
            return new ActualTask();
        worker.start();
       * Called from ProgressBarDemo to find out how much work needs
       * to be done.
      public int getLengthOfTask() {
        return lengthOfTask;
       * Called from ProgressBarDemo to find out how much has been done.
      public int getCurrent() {
        return current;
      public void stop() {
        current = lengthOfTask;
       * Called from ProgressBarDemo to find out if the task has completed.
      public boolean done() {
        if (current >= lengthOfTask)
          return true;
        else
          return false;
      public String getMessage() {
        return statMessage;
       * The actual long running task.  This runs in a SwingWorker thread.
      class ActualTask {
        ActualTask () {
          current = -1;
          statMessage = "";
          resultStream = AIUtil.getInputStreamFromEncZip(cryptedFileNameAndPath); //here the decryption happens
          current = 0;
          statMessage = "";
      }The code that calls decryption and displays waitWindow
          final WaitSplash wS = new WaitSplash("Please wait...");
          final DecryptFile cryptedTemplate = new DecryptFile (this.templateFile);
          cryptedTemplate.go();
          while (! cryptedTemplate.done()) {
            try {
              wait();
            } catch (Exception e) { }
          this.templateInputStream = cryptedTemplate.getDecryptedInputStream();
          wS.close();Thanks, thanks, thanks in advance!
    Edoardo

    Maybe you can try setting the priority of the long-running thread to be lower? so that the UI will be more responsive...

  • Problem with threads and graphics

    I have a thread that chooses paths for a Travelling salesman problem, it then calls a TSPdraw class and passes it the path, which the class then draws. the problem is when i have two threads it creates two windows but only draws a path in one of them. any ideas where i`m going wrong

    Are you using swing components? Swing isn't threadsafe. If you have multiple threads that want to update your UI you need to use the SwingUtilities.invokeLater(...)or invokeAndWait(...). There is a page in the swing tutorial about this at: http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html

  • Problem with threads and ProgressMonitor

    Dear Friends:
    I have a little problem with a thread and a ProgressMonitor. I have a long time process that runs in a thread (the thread is in an separate class). The thread has a ProgressMonitor that works fine and shows the tasks progress.
    But I need deactivate the main class(the main class is the user interface) until the thread ends.
    I use something like this:
    LongTask myTask=new LongTask();
    myTask.start();
    myTask.join();
    Now, the main class waits for the task to end, but the progress monitor don`t works fine: it shows only the dialog but not the progress bar.
    What's wrong?

    Is the dialog a modal dialog? This can block other UI updates.
    In general, you should make sure that it isn't modal, and that your workThread has a fairly low priority so that the UI can do its updating

  • Problem with threads and/or memory

    I'm developing an application where there are 3 threads. One of them sends a request to the other, and if the 2nd can't answer it, it sends it to the 3rd (similar to CPU -> CACHE -> MEMORY). When i run the program with 1000-10.000 requests, no problem occurs. When i run it with 300.000-1.000.000 requests, it sometimes hangs. Is this a problem with the garbage collector, or should it be related to the threads mecanism.
    (note: eache thread is in execution using a finite state machine)

    i had been running the program inside Netbeans.
    Running the jar using the command line outside
    Netbeans i have no more problems... Does Netbeans use
    it's own JVM?Depends how you set it up, but look under the options. There are settings for the compiler and jvm that it uses.

Maybe you are looking for