⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myapplet.java

📁 智能卡多应用一直是业界的重要课题
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/**
 *        Title:  Applet frame
 *
 *      Project:  Universal Application Specification v1.0 for PBOCv2
 *
 *    Copyright:  Copyright (c) CUP 2005
 *      Company:  China Unionpay Co., Ltd
 *
 *  Platform   :  Java virtual machine
 *  Language   :  1.3.0-C
 *  Devl tool  :  Borland (c) JBuilder 4.0 *
 *  author     :  Meng Hongwen<hwmeng@chinaunionpay.com>
 *  version 1.0
 */

/*
 * Package name
 */
package cupUAPP;

import javacard.framework.*;
import visa.openplatform.*;
import javacardx.crypto.*;

public class MyApplet extends javacard.framework.Applet
{
    // op routines
    private ProviderSecurityDomain securityObject;
    private byte secureChannel = (byte)0xFF;
    private boolean channelOpened = false;

    // system template defination
    private static byte UAPP_TAG_OBJECT  = (byte)0x7F;
    private static byte UAPP_TAG_CONTENT = (byte)0x70;

    // system tag defination
    private static byte UAPP_TAG_OID    = (byte)0x50;
    private static byte UAPP_TAG_ATTRIB = (byte)0x51;
    private static byte UAPP_TAG_OAC    = (byte)0x52;
    private static byte UAPP_TAG_ACL    = (byte)0x53;
    private static byte UAPP_TAG_KEY    = (byte)0x54;
    private static byte UAPP_TAG_RAWDATA= (byte)0x55;
    private static byte UAPP_TAG_DOL    = (byte)0x56;
    private static byte UAPP_TAG_MAC    = (byte)0x57;

    // Default Control Key
    private  byte[] uapp_def_mck = new byte[]{
	(byte)0x11,(byte)0x11,(byte)0x11,(byte)0x11,(byte)0x11,(byte)0x11,(byte)0x11,(byte)0x11,
        (byte)0x22,(byte)0x22,(byte)0x22,(byte)0x22,(byte)0x22,(byte)0x22,(byte)0x22,(byte)0x22
    };

    // System operate objects
    private static tjrandgenerator r;
    private static penCipher       c;
    private static tjuapdu         ai;
    private static tjMemoryManager mm;

    // Container & Object Management
    private Object[]          oidArray;
    private static byte[]     oiduid = new byte[(short)8];
    private static byte       oidversion;
    private static short      oidcount;
    private static boolean    oidbAllowInsert;
    private static tjoidEntry oidCurrentApp, oidCursor;
    //------------------------------------------------
    private static short      __us_aOffset;
    private static short      __us_dOffset;
    //------------------------------------------------
    protected MyApplet(byte[] buffer, short offset, byte length)
    {
        register();

        securityObject = OPSystem.getSecurityDomain();
        OPSystem.setCardContentState(OPSystem.APPLET_PERSONALIZED);

        ai = new tjuapdu();
        r  = new tjrandgenerator();
        c  = new penCipher();

        // initlize container
        oidArray = new Object[constdef.ct_oid_entrys];
        oidcount = (short)0;
        oidversion = (byte)0x01;
        r.generateSecureRnd((byte)8);
        r.getRndValue(oiduid);

        // create memory manager
        mm = new tjMemoryManager();
        mm.initlize();
    }
    //------------------------------------------------
    public static void install(byte[] bArray, short bOffset, byte bLength) throws ISOException
    {
        new MyApplet (bArray, bOffset, (byte)bLength );
    }
    //------------------------------------------------
    public boolean select()
    {
        reset_security();
        r.revokeRnd();

        // resest container
        oidbAllowInsert = false;
        oidCurrentApp = null;

        return true; //mm.reset();
    }
    //------------------------------------------------
    public void deselect()
    {
        reset_security();
        if (oidCurrentApp!=null)
            if ( oidCurrentApp.usCount <(short)1) oidCurrentApp.used = false;
        return;
    }
    //------------------------------------------------
    public void reset_security()
    {
        if(secureChannel != (byte)0xFF) {
            try {
                securityObject.closeSecureChannel(secureChannel);
            }
            catch(CardRuntimeException cre2)
            {
                // channel number is invalid. this case is ignored
            }
            secureChannel = (byte)0xFF;
            channelOpened = false;
        }
        return;
    }
    //------------------------------------------------
    public void process(APDU apdu) throws ISOException
    {
        byte[] apduBuffer;
        short  dl;
        boolean  rc=false;

        if (selectingApplet())     return;

        apduBuffer = apdu.getBuffer();
        ai.cla = (byte)apduBuffer[ISO7816.OFFSET_CLA];
        ai.ins = (byte)apduBuffer[ISO7816.OFFSET_INS];
        ai.p1 = (byte)apduBuffer[ISO7816.OFFSET_P1];
        ai.p2 = (byte)apduBuffer[ISO7816.OFFSET_P2];
        ai.lc = (short)(apduBuffer[ISO7816.OFFSET_LC]& 0x0FF);

        if( ai.APDUContainData()) {
           dl = apdu.setIncomingAndReceive();
           Util.arrayCopyNonAtomic(apduBuffer,(short)5, ai.pdata,(short)0,dl);
           ai.lc = dl;
        } else {
           ai.le = ai.lc;
           ai.lc = (short)0;
        }

        rc = handleEvent();

        if (rc)
           if(ai.le>(short)0) {
              Util.arrayCopyNonAtomic(ai.pdata,(short)0, apduBuffer,(short)0,ai.le);
              apdu.setOutgoingAndSend((short)0, ai.le);
           }
    }
    //------------------------------------------------
    public boolean handleEvent() throws ISOException
    {
        switch (ai.ins) {
           case constdef.INS_CHALLENGE:    return getChallenge();

           case constdef.INS_INSERTOBJECT: return insertObject();
           case constdef.INS_ACCESSOBJECT: return accessObject();
           case constdef.INS_GETSTATUS:    return getstatus();
           case constdef.INS_SELECTAPP:    return selectApplication();

           case constdef.INS_DEBUGDEBUG:   return debug_debug();
        }

        ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
        return false;
    }
    //------------------------------------------------
    public boolean getChallenge() throws ISOException
    {
       if( ai.cla != (byte)0x00)
            ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);

       if ( ai.p1 != (byte)0 && ai.p2 != (byte)0 )
           ISOException.throwIt(ISO7816.SW_WRONG_P1P2);

       if ((ai.le!=(short)4)&&(ai.le!=(short)8))
           ISOException.throwIt(constdef.SW_E_DATAINVAILD);

       r.generateSecureRnd((byte)ai.le);
       ai.le = (short)r.getRndValue(ai.pdata);
       return true;
    }
    //------------------------------------------------
    public boolean getstatus() throws ISOException
    //  applet_version1 + uid8 + maxnum2 + count2 + TOTAL_memory + FREE_memory
    {
       if( ai.cla != (byte)0x80)
            ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);

       if ( ai.p1 != (byte)0 && ai.p2 != (byte)0 )
           ISOException.throwIt(ISO7816.SW_WRONG_P1P2);

       ai.pdata[0] = (byte)0x01;

       Util.arrayCopyNonAtomic(oiduid,(short)0,ai.pdata,(short)1,(short)8);
       Util.setShort(ai.pdata,(short)9,constdef.ct_oid_entrys);
       Util.setShort(ai.pdata,(short)11,oidcount);
       Util.setShort(ai.pdata,(short)13,constdef.ct_memory_size);
       Util.setShort(ai.pdata,(short)15,mm.remain);
       ai.le = (short)17;
       return true;
    }
    //------------------------------------------------
    private boolean findEntryByOid(byte[] pOid ,short ol)
    {
        for(short i=0; i<oidcount; i++ ) {
            oidCursor = (tjoidEntry)oidArray[i];
            if (oidCursor.isEqual(pOid,ol)) {
              oidCurrentApp = oidCursor; // change current application
              oidCurrentApp.reset();
              return true;
            }
        }
        return false;
    }
    //------------------------------------------------
    private boolean findFreeEntry()
    {
        for(short i=0; i<oidcount; i++ ) {
            oidCursor = (tjoidEntry)oidArray[i];
            if (!oidCursor.used) {
               oidCurrentApp = oidCursor;
               oidCurrentApp.reset();
               return true;
            }
        }
        return false;
    }
    //------------------------------------------------
    private short  searchOrignalACLByTag(short toFindTag)
    {
        short   i,aTag;

        for(i=(short)0; i<ai.usTempShort;) {
           if ((ai.ucTemp128[i]&0x01F) == 0x1F ) {
              aTag = Util.makeShort(ai.ucTemp128[i],ai.ucTemp128[(short)(i+1)]);
              i++;
              i++;
           } else {
              aTag = (short)(ai.ucTemp128[i]&0x0FF);
              i++;
           }

           if ( aTag == toFindTag ) {
              return Util.makeShort(ai.ucTemp128[i],ai.ucTemp128[(short)(i+1)]);
           }
        }
        return (short)(-1);
    }
    //------------------------------------------------
    private boolean  expandTLVObject(short dAddress, short dSize, byte[] pdata, short usPos, short length, short groupAC)
    {
       short     aTag,eatlen;
       boolean   bStructureTag;
       short     kOffset,defaultAC;

       __us_aOffset = (short)(ai.usTempCount<<3/**8*/);
       while(length>0) {

          if ( (short)(pdata[usPos]&0x020)==(short)0x20) bStructureTag = true;
          else bStructureTag = false;

          if ((pdata[usPos]&0x01F) == 0x1F ) {
             eatlen =2;
             aTag = Util.makeShort(pdata[usPos],pdata[(short)(usPos+1)]);
          } else {
             eatlen =1;
             aTag = (short)(pdata[usPos]&0x0FF);
          }

          usPos += eatlen;
          length -= eatlen;

          if ((pdata[usPos]&0x080)==0x80) {  // now we only handle 1 byte length
             usPos++;
             length--;

             eatlen = (short)(pdata[usPos]&0x0FF);
             usPos++;
             length--;
          } else {
             eatlen = (short)(pdata[usPos]&0x0FF);
             usPos++;
             length--;
          }

          // find AC by Tag
          defaultAC = searchOrignalACLByTag(aTag);
          if ( defaultAC == (short)-1) defaultAC = groupAC;

          if (!bStructureTag) {
             if (ai.usTempCount >= constdef.ct_NTagInObject) return false; // too tags

             // store TAG AC offset,length
             Util.setShort(ai.ucTemp256,__us_aOffset,aTag);     __us_aOffset++; __us_aOffset++;
             Util.setShort(ai.ucTemp256,__us_aOffset,defaultAC);__us_aOffset++; __us_aOffset++;
             Util.setShort(ai.ucTemp256,__us_aOffset,__us_dOffset);  __us_aOffset++; __us_aOffset++;

             // is Key Object?
             if ( aTag == UAPP_TAG_KEY ){
                 Util.setShort(ai.ucTemp256,__us_aOffset,(short)(eatlen-2));   __us_aOffset++; __us_aOffset++;
                 // Store Key
                 kOffset = Util.makeShort(pdata[usPos],pdata[(short)(usPos+1)]);
                 mm.memcpyIN(dAddress, dSize, kOffset,pdata,(short)(usPos+2),(short)(eatlen-2));
             } else {
                 Util.setShort(ai.ucTemp256,__us_aOffset,eatlen);   __us_aOffset++; __us_aOffset++;
                 // store content

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -