Code: Select all
package online;
import javacard.framework.*;
public class online extends Applet {
final static byte WALLET_CLA = (byte)0xA0;
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 short MAX_BALANCE = 10000;
final static short MAX_TRANSACTION_AMOUNT = 5000;
final static byte PIN_TRY_LIMIT =(byte)0x03;
final static byte MAX_PIN_SIZE =(byte)0x08;
final static short SW_VERIFICATION_FAILED = 0x6300;
final static short SW_PIN_VERIFICATION_REQUIRED = 0x6301;
final static short SW_INVALID_TRANSACTION_AMOUNT = 0x6A83;
final static short SW_EXCEED_MAXIMUM_BALANCE = 0x6A84;
final static short SW_NEGATIVE_BALANCE = 0x6A85;
final static byte GET_ACCOUNT_INFO = (byte) 41;
final static byte HASH_VALUE_LENGTH = (byte) 8;
final static byte NAME = (byte) 20;
final static byte ACCOUNT_NUMBER = (byte) 9;
final static byte EXPIRATION_DATE = (byte) 4;
private static byte[] name = {(byte)0x44, (byte)0x30, (byte)0x35, (byte)0x31, (byte)0x30, (byte)0x36, (byte)0x30, (byte)0x31, (byte)0x32};
private static byte[] account_number = {(byte)0x44, (byte)0x30, (byte)0x35, (byte)0x31, (byte)0x30, (byte)0x36, (byte)0x30, (byte)0x31, (byte)0x32};
private static byte[] expiration_date = {(byte)0x44, (byte)0x30, (byte)0x35, (byte)0x31, (byte)0x30, (byte)0x36, (byte)0x30, (byte)0x31, (byte)0x32};
OwnerPIN pin;
short balance;
/**
* called by the JCRE to create an applet instance
* @param bArray
* @param bOffset
* @param bLength
*/
public static void install(byte[] bArray, short bOffset, byte bLength) {
new online(bArray, bOffset, bLength);
}
private online (byte[] bArray, short bOffset, byte bLength){
pin = new OwnerPIN(PIN_TRY_LIMIT, MAX_PIN_SIZE);
bArray[0] = '1';
bArray[1] = '1';
bArray[2] = '1';
bArray[3] = '1';
bOffset = 0;
bLength = 4;
pin.update(bArray, bOffset, bLength);
register();
}
/**
*
* @return
*/
public boolean select() {
if (pin.getTriesRemaining() == 0)
return false;
return true;
}
public void deselect() {
pin.reset();
}
/**
*
* @param apdu
*/
public void process(APDU apdu) {
byte[] buffer = apdu.getBuffer();
if (selectingApplet())
return;
if (buffer[ISO7816.OFFSET_CLA] != WALLET_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 GET_ACCOUNT_INFO: get_account_info(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 ((creditAmount > MAX_TRANSACTION_AMOUNT)
|| (creditAmount<0))
ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
balance=(short)(balance+creditAmount);
}
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);
}
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);
}
private void get_account_info(APDU apdu) {
short total_bytes = (short) 41;
short le = apdu.setOutgoing();
apdu.setOutgoingLength(total_bytes);
apdu.sendBytesLong(name, (short)0, (short) name.length);
apdu.sendBytesLong(account_number, (short)0, (short)account_number.length);
apdu.sendBytesLong(expiration_date, (short)0,(short)expiration_date.length);
apdu.sendBytes((short)0, HASH_VALUE_LENGTH);
return;
}
}