Как мне нужно изменить код в Кошельке с JavaCard для правильной работы при изменении константы MAX_TRANSACTION_AMOUNT? - PullRequest
0 голосов
/ 25 марта 2020

Я хочу изменить переменную 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
...