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

📄 cuppbocep.java

📁 在java卡上实现的PBOC电子钱包应用
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/**
 * 
 *------------------------------------------------------------------------------
 *  @Project name    :  PBOC 2.0 EP Simple version
 *                      - Java Card applet -
 *
 *  @Platform        :  Java virtual machine
 *  @Language        :  1.3.0-C
 *  @Devltool        :  Borland (c) JBuilder 4.0
 *
 *  @Originalauthor  : Menghongwen@gmail.com 
 *  @Date            : Tue Apr 04 10:44:36 CST 2006
 *------------------------------------------------------------------------------
 */

package PbocEpSimpleVersion;

import javacard.framework.AID;
import javacard.framework.APDU;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.JCSystem;
import javacard.framework.Util;

public class CupPBOCEP extends javacard.framework.Applet
{

	// APDU object
	private tjuapdu  apduin;
    // filesystem ready flag
    private boolean bFSReady;
    // personalized flag
    private boolean bPersoed;
    // Blocked flag
    private boolean bCardBlocked;
    private boolean bAppBlocked;
    private boolean bAppBLKALWS;
    
    // owner PIN
    private tjPIN  pinOwner,pinUnBlock;

    // FILE System
    private tjefbinary ef15, ef16,ef17;
    private tjelinearfix ef18,ef19;

    //------------------------------------------------
    protected CupPBOCEP(byte[] buffer, short offset, byte length)
    {
        register();

        bPersoed = false;
        apduin = new tjuapdu();

        pinOwner = new tPIN();
        pinUnBlock = new tPIN();
        bFSReady = false;
        bAppBlocked = false;
        bCardBlocked = false;
        bAppBLKALWS = false;
    }
    //------------------------------------------------
    public static void install(byte[] bArray, short bOffset, byte bLength) throws ISOException
    {
        new CupPBOCEP (bArray, bOffset, (byte)bLength );
    }
    //------------------------------------------------
    public boolean select()
    {
        pinOwner.reset();
        if (ef17!=null) ((tjpbocIDU)ef17).reset();
        return true;
    }
    //------------------------------------------------
    public void deselect()
    {
        return;
    }
    //------------------------------------------------
    public void process(APDU apdu) throws ISOException
    {
        byte[] apduBuffer;
        short  dl;
        boolean  rc=false;
        short bytesRead;
        short echoOffset;

        apduBuffer = apdu.getBuffer();
        
        if (selectingApplet())  { // return FCI
            apduBuffer[0] = (byte)0x6F;
            apduBuffer[1] = (byte)0x22;
            apduBuffer[2] = (byte)0x84;
            apduBuffer[3] = (byte)0x10;
            apduBuffer[4] = (byte)0xd1;
            apduBuffer[5] = (byte)0x56;
            apduBuffer[6] = (byte)0x00;
            apduBuffer[7] = (byte)0x00;
            apduBuffer[8] = (byte)0x01;
            apduBuffer[9] = (byte)0x45;
            apduBuffer[10] = (byte)0x44;
            apduBuffer[11] = (byte)0x2f;
            apduBuffer[12] = (byte)0x45;
            apduBuffer[13] = (byte)0x50;
            apduBuffer[14] = (byte)0x00;
            apduBuffer[15] = (byte)0x00;
            apduBuffer[16] = (byte)0x00;
            apduBuffer[17] = (byte)0x00;
            apduBuffer[18] = (byte)0x00;
            apduBuffer[19] = (byte)0x00;
            apduBuffer[20] = (byte)0xA5;
            apduBuffer[21] = (byte)0x0f;
            apduBuffer[22] = (byte)0x50;
            apduBuffer[23] = (byte)0x08;
            apduBuffer[24] = (byte)'M';
            apduBuffer[25] = (byte)'o';
            apduBuffer[26] = (byte)'b';
            apduBuffer[27] = (byte)'i';
            apduBuffer[28] = (byte)'l';
            apduBuffer[29] = (byte)'e';
            apduBuffer[30] = (byte)'E';
            apduBuffer[31] = (byte)'P';
            apduBuffer[32] = (byte)0x9F;
            apduBuffer[33] = (byte)0x08;
            apduBuffer[34] = (byte)0x01;
            apduBuffer[35] = (byte)0x02;

            apdu.setOutgoingAndSend((short)0, (short)36);
            if(bAppBlocked||bCardBlocked||bAppBLKALWS) ISOException.throwIt(constdef.SW_E_APPBLK);
            return;
        }

        if(bCardBlocked||bAppBLKALWS) ISOException.throwIt((short)0x9303);
        
        apduin.cla = (byte)apduBuffer[ISO7816.OFFSET_CLA];
        apduin.ins = (byte)apduBuffer[ISO7816.OFFSET_INS];
        apduin.p1 = (byte)apduBuffer[ISO7816.OFFSET_P1];
        apduin.p2 = (byte)apduBuffer[ISO7816.OFFSET_P2];
        apduin.lc = (short)(apduBuffer[ISO7816.OFFSET_LC]& 0x0FF);
        
        if( apduin.APDUContainData()) {

           bytesRead = apdu.setIncomingAndReceive();
           echoOffset = (short)0;

           while ( bytesRead > 0 ) {
              Util.arrayCopyNonAtomic(apduBuffer, ISO7816.OFFSET_CDATA, apduin.pdata, echoOffset, bytesRead);
              echoOffset += bytesRead;
              bytesRead = apdu.receiveBytes(ISO7816.OFFSET_CDATA);
           }
           apduin.lc = echoOffset;

        } else {
           apduin.le = apduin.lc;
           apduin.lc = (short)0;
        }

        rc = handleEvent(apdu.getBuffer());

        if (rc) {
           dl = apduin.le;
           if(dl>(short)0) {
              Util.arrayCopyNonAtomic(apduin.pdata,(short)0, apduBuffer,(short)0,dl);
              apdu.setOutgoingAndSend((short)0, apduin.le);
           }
        }
    }
    //------------------------------------------------
    public boolean handleEvent(byte[] apb) throws ISOException
    {
        if (bFSReady) {
        	if(!bAppBlocked) {
        	switch (apduin.ins) {
             case constdef.INS_VERIFY:      return verify_pin();
             case constdef.INS_CHANGE:      return change_pin();
             case constdef.INS_UNBLOCK:     return unblock_pin();
             case constdef.INS_LOCKCARD:    return lock_card();
             case constdef.INS_READ_BIN:    return read_update_binary((byte)'R');
             case constdef.INS_UPDATE_BIN:  return read_update_binary((byte)'U');
             case constdef.INS_READ_REC:    return read_record();
             case constdef.INS_UPDATE_REC:  return update_record();
             case constdef.INS_GETBAL:      return get_balance();
             case constdef.INS_INITTRANS:
                if( apduin.cla != constdef.CUP_CLA )
                   ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
                if ( apduin.p1 ==(byte)0x1) return init_purchase();
                if ( apduin.p1 ==(byte)0x0) return init_load();
                ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
                break;
             case constdef.INS_PURCHASE:    return debit_purchase();
             case constdef.INS_LOAD:        return credit_load();
             case constdef.GET_TRANS_PROOF: return get_tp();
             case constdef.APP_BLOCK:       return app_block();
             case constdef.APP_UNBLOCK:     return app_unblock();
             case constdef.CARD_BLOCK:      return card_block();
             case constdef.INS_CHALLENGE:   return getcha();
            } // end of switch
        	} else {
        		switch (apduin.ins) {
                  case constdef.APP_UNBLOCK:     return app_unblock();
                  case constdef.CARD_BLOCK:      return card_block();
                  case constdef.INS_CHALLENGE:   return getcha();
                  default: ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 
        		} // end switch
        	} // end of else
        } else { // create file system
           if (apduin.ins==constdef.INS_CREATEFS)
               if ( apduin.p1 ==(byte)0x0)  return create_fs();
        }

        ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
        return false;
    }
    //------------------------------------------------
    public boolean create_fs() throws ISOException
    // create file system
    {
        byte[] ptr=null;

        if( apduin.cla != constdef.CUP_CLA )
            ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);

        if ( apduin.p1 != (byte)0x00 || apduin.p2 != (byte)0x0)
            ISOException.throwIt(ISO7816.SW_WRONG_P1P2);

        ptr = new byte[30];
        if(ptr==null)
            ISOException.throwIt(ISO7816.SW_FILE_FULL);
        ef15 = new tjefbinary(ptr,(short)30, (byte)0x00,(byte)0x02);

        ptr = new byte[55];
        if(ptr==null)
            ISOException.throwIt(ISO7816.SW_FILE_FULL);
        ef16 = new tjefbinary(ptr,(short)55,  (byte)0x00,(byte)0x02);
        ef18 = new tjelinearfix((short)10, (short)0x17,(byte)0x01,(byte)0xff);
        ef19 = new tjelinearfix((short)20, (short)0x12,(byte)0xFF,(byte)0xFF);  
        ef17 = new tjpbocIDU(ef19,ef18);

        Util.arrayFillNonAtomic(apduin.ucTemp256,(short)0,(short)32,(byte)0x11);
        apduin.ucTemp256[0] = (byte)0x06;
        apduin.ucTemp256[1] = (byte)0x01;
        ef19.writerec((byte)0x01,apduin.ucTemp256);
        
        ef18.cyclicMode();
        bFSReady = true;
        apduin.le = (short)0;
        return true;
    }
    //------------------------------------------------
    public boolean verify_pin() throws ISOException
    // PBOC 2.0 verify command
    {
        if( apduin.cla != (byte)0x0 )
            ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);

        if (apduin.lc>(short)8)
           ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);

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

        if (pinOwner.remainTimes() == (short)0)
              ISOException.throwIt(constdef.SW_E_PINBLKED);

        if (apduin.lc<(short)8)
           Util.arrayFillNonAtomic(apduin.pdata,apduin.lc,(short)(8-apduin.lc),(byte)0xFF);

        if(!pinOwner.verify(apduin.pdata))
              ISOException.throwIt((short)((short)0x6c00 + pinOwner.remainTimes()));

        apduin.le = (short)0;
        return true;
    }
    //------------------------------------------------
    public boolean reload_pin() throws ISOException
    // PBOC 2.0 reload PIN
    {
    	short rc; 
    	
    	Util.arrayCopyNonAtomic(apduin.pdata,(short)(apduin.lc-4),apduin.ucTemp256,(short)0,(short)4);
    	rc = ((tjpbocIDU)ef17).unwrap_apdu((byte)0x05,apduin,true);
    	
    	if(rc==(short)1) 	ISOException.throwIt(constdef.SW_E_REFDATA);
    	if(rc==(short)2) 	ISOException.throwIt(constdef.SW_E_SMDATA);
    	
    	Util.arrayFillNonAtomic(apduin.ucTemp256,(short)0,(short)8,(byte)0xFF);
    	Util.arrayCopyNonAtomic(apduin.pdata,(short)0,apduin.ucTemp256,(short)0,(short)(apduin.lc-4));
    	pinOwner.setNewValue(apduin.ucTemp256);
        return true;
    }
    //------------------------------------------------    
    public boolean change_pin() throws ISOException
    // PBOC 2.0 change pin command
    {
        short  i,j;

        apduin.le = (short)0;
        
        if( apduin.cla != constdef.CUP_CLA )
            ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
        
        if ( apduin.p2 != (byte)0x0)
            ISOException.throwIt(ISO7816.SW_WRONG_P1P2);

        if (apduin.lc<(short)0x06)
            ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
        
        
        if ( apduin.p1 == (byte)0x0) return reload_pin(); 
        if ( apduin.p1 != (byte)0x01)
            ISOException.throwIt(ISO7816.SW_WRONG_P1P2);

        if (apduin.lc>(short)0x0d)
           ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);

        if (pinOwner.remainTimes() == (short)0)
             ISOException.throwIt(constdef.SW_E_PINBLKED);

        // initilize parameter
        i = (short)0;
        j  = (short)0;
        Util.arrayFillNonAtomic(apduin.ucTemp256,(short)0,(short)16,(byte)0xFF);

        // retrieve old pin
        for(; i<apduin.lc;i++) {
           if ( apduin.pdata[i] !=(byte)0xFF)
              apduin.ucTemp256[j++] = apduin.pdata[i];
           else break;
        }

        i++; // skip 0xFF
        // padding 0xff
        while(j <(short)8)
            j++;

        // padding new pin
        for(; i<apduin.lc;i++)
           apduin.ucTemp256[j++] = apduin.pdata[i];

        if(!pinOwner.verifyChange(apduin.ucTemp256))
             ISOException.throwIt((short)((short)0x6c00 + pinOwner.remainTimes()));

        return true;
    }
    //------------------------------------------------
    public boolean unblock_pin() throws ISOException
    {
        short rc;
        
    	if( apduin.cla != (byte)0x84 )
            ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);

        if ( apduin.p1 != (byte)0x00)
            ISOException.throwIt(ISO7816.SW_WRONG_P1P2);

        if ( apduin.p2 != (byte)0x01)
            ISOException.throwIt(ISO7816.SW_WRONG_P1P2);

        if (apduin.lc!=(short)0x0c)
           ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);

        rc = ((tjpbocIDU)ef17).unwrap_apdu((byte)0x04,apduin,false);
        switch(rc) {
           case (short)0x01: ISOException.throwIt(constdef.SW_E_REFDATA);            
           case (short)0x02: ISOException.throwIt(constdef.SW_E_SMDATA);        	
        }

        if (pinOwner.remainTimes() > (short)0)
        	ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);

        Util.arrayFillNonAtomic(apduin.ucTemp256,(short)0,(short)8,(byte)0xFF);
        Util.arrayCopyNonAtomic(apduin.pdata,(short)0,apduin.ucTemp256,(short)0,apduin.lc);
        
        if(!pinOwner.verify(apduin.ucTemp256))
        	ISOException.throwIt(ISO7816.SW_WRONG_DATA);
        pinOwner.resetCounter();
        apduin.le = (short)0;
        return true;
    }
    //------------------------------------------------
    public boolean lock_card() throws ISOException
    {
        if( apduin.cla != constdef.CUP_CLA )
            ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);

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

        if (apduin.lc!=(short)0x0)
           ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);

        if (bPersoed)
           ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);

        bPersoed = true;
        return true;
    }
    //------------------------------------------------
    public boolean getcha() throws ISOException
    {
        if( apduin.cla != (byte)0x0 )
            ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);

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

       if (apduin.le!=(short)4)
           ISOException.throwIt(ISO7816.SW_WRONG_DATA);

⌨️ 快捷键说明

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