📄 cuppbocep.java
字号:
/**
*
*------------------------------------------------------------------------------
* @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 + -