Я хочу изменить переменную MAX_TRANSACTION_AMOUNT, чтобы она была 600 (десятичная) = 0x258 (шестнадцатеричная). Я внес необходимые изменения в функцию кредита (я проверяю, что numBytes равно 2), но я не уверен, что это правильно. И я полагаю, что мне нужно внести некоторые изменения в код из wallet.sr c, но я не знаю, что мне следует изменить или добавить. Я предоставлю код, который у меня есть ниже. Я ценю все ответы. Спасибо.
кошелек. java
package com.oracle.jcclassic.samples.wallet;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.OwnerPIN;
public class Wallet extends Applet {
/* constants declaration */
// code of CLA byte in the command APDU header
final static byte Wallet_CLA = (byte) 0x80;
// codes of INS byte in the command APDU header
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;
// maximum balance
final static short MAX_BALANCE = 0x7FFF;
// maximum transaction amount
//I have modifies the value
final static short MAX_TRANSACTION_AMOUNT = 0x258;
// maximum number of incorrect tries before the
// PIN is blocked
final static byte PIN_TRY_LIMIT = (byte) 0x03;
// maximum size PIN
final static byte MAX_PIN_SIZE = (byte) 0x08;
// signal that the PIN verification failed
final static short SW_VERIFICATION_FAILED = 0x6300;
// signal the the PIN validation is required
// for a credit or a debit transaction
final static short SW_PIN_VERIFICATION_REQUIRED = 0x6301;
// signal invalid transaction amount
// amount > MAX_TRANSACTION_AMOUNT or amount < 0
final static short SW_INVALID_TRANSACTION_AMOUNT = 0x6A83;
// signal that the balance exceed the maximum
final static short SW_EXCEED_MAXIMUM_BALANCE = 0x6A84;
// signal the the balance becomes negative
final static short SW_NEGATIVE_BALANCE = 0x6A85;
/* instance variables declaration */
OwnerPIN pin;
short balance;
private Wallet(byte[] bArray, short bOffset, byte bLength) {
pin = new OwnerPIN(PIN_TRY_LIMIT, MAX_PIN_SIZE);
byte iLen = bArray[bOffset]; // aid length
bOffset = (short) (bOffset + iLen + 1);
byte cLen = bArray[bOffset]; // info length
bOffset = (short) (bOffset + cLen + 1);
byte aLen = bArray[bOffset]; // applet data length
pin.update(bArray, (short) (bOffset + 1), aLen);
register();
} // end of the constructor
public static void install(byte[] bArray, short bOffset, byte bLength) {
// create a Wallet applet instance
new Wallet(bArray, bOffset, bLength);
} // end of install method
@Override
public void process(APDU apdu) {
byte[] buffer = apdu.getBuffer();
// check SELECT APDU command
if (apdu.isISOInterindustryCLA()) {
if (buffer[ISO7816.OFFSET_INS] == (byte) (0xA4)) {
return;
}
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
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;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
} // end of process method
private void credit(APDU apdu) {
// access authentication
if (!pin.isValidated()) {
ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
}
byte[] buffer = apdu.getBuffer();
// Lc byte denotes the number of bytes in the
// data field of the command APDU
byte numBytes = buffer[ISO7816.OFFSET_LC];
// indicate that this APDU has incoming data
// and receive data starting from the offset
// ISO7816.OFFSET_CDATA following the 5 header
// bytes.
byte byteRead = (byte) (apdu.setIncomingAndReceive());
// it is an error if the number of data bytes
// read does not match the number in Lc byte
if ((numBytes != 2) || (byteRead != 2)) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
// get the credit amount
byte creditAmountF = buffer[ISO7816.OFFSET_CDATA];
byte creditAmountS = buffer[ISO7816.OFFSET_CDATA + 1];
short creditAmount = 0;
creditAmount = (short)( (creditAmountF<<8) | (creditAmountS & 0xFF) );
// check the credit amount
if ((creditAmount > MAX_TRANSACTION_AMOUNT) || (creditAmount < 0)) {
ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
}
// check the new balance
if ((short) (balance + creditAmount) > MAX_BALANCE) {
ISOException.throwIt(SW_EXCEED_MAXIMUM_BALANCE);
}
// credit the amount
balance = (short) (balance + creditAmount);
}
private void debit(APDU apdu) {
// access authentication
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);
}
// get debit amount
byte debitAmount = buffer[ISO7816.OFFSET_CDATA];
// check debit amount
if ((debitAmount > MAX_TRANSACTION_AMOUNT) || (debitAmount < 0)) {
ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
}
// check the new balance
if ((short) (balance - debitAmount) < (short) 0) {
ISOException.throwIt(SW_NEGATIVE_BALANCE);
}
balance = (short) (balance - debitAmount);
} // end of debit method
private void getBalance(APDU apdu) {
byte[] buffer = apdu.getBuffer();
short le = apdu.setOutgoing();
if (le < 2) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
apdu.setOutgoingLength((byte) 2);
buffer[0] = (byte) (balance >> 8);
buffer[1] = (byte) (balance & 0xFF);
apdu.sendBytes((short) 0, (short) 2);
} // end of getBalance method
private void verify(APDU apdu) {
byte[] buffer = apdu.getBuffer();
// retrieve the PIN data for validation.
byte byteRead = (byte) (apdu.setIncomingAndReceive());
if (pin.check(buffer, ISO7816.OFFSET_CDATA, byteRead) == false) {
ISOException.throwIt(SW_VERIFICATION_FAILED);
}
} // end of validate method
} // end of class Wallet
В кошелек.sr c я добавил строку
0x80 0x30 0x00 0x00 0x02 0x258 0x7F;
//0x6A83 = SW_INVALID_TRANSACTION_AMOUNT