JavaCard Applet Development Related Questions and Answers.
-
andromeda92
- Posts: 38
- Joined: Tue Aug 18, 2020 6:08 pm
- Points :320
-
Contact:
Post
by andromeda92 » Sun Aug 30, 2020 10:25 pm
Hi,
is it possible to install parameters to applet using
JCIDE instead of using gp.exe or GPShell.exe,
it is in order to test with the JVM (JAVACOS Virtual contact).
Thanks for your help.
Edit1 :
I have found, when i install applet on debug, i can put parameter, but i have an error:
my parameter is 31323334FFFFFFFF
Code: Select all
Install Applet error: Install Applet failed. Send: 80 E6 0C 00 22 05 31 32 33 34 35 06 31 32 33 34 35 00 06 31 32 33 34 35 00 01 00 0A C9 08 31 32 33 34 FF FF FF FF 00, Recv: 69 85.
any idea ?
Last edited by
andromeda92 on Sun Aug 30, 2020 11:05 pm, edited 1 time in total.
-
andromeda92
- Posts: 38
- Joined: Tue Aug 18, 2020 6:08 pm
- Points :320
-
Contact:
Post
by andromeda92 » Sun Aug 30, 2020 11:05 pm
I do not understand but now it works, I can check the pin code that I put in parameter, and change it.
CODE:
Code: Select all
package PackageWallet ;
import javacard.framework.*;
public class AppletWallet extends Applet {
/* constants declaration */
// code of CLA byte in the command APDU header
final static byte Wallet_CLA =(byte)0xB0;
// 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;
final static byte CHANGE = (byte) 0x60;
// maximum balance
final static short MAX_BALANCE = 0x7FFF;
// maximum transaction amount
final static byte MAX_TRANSACTION_AMOUNT = 127;
// 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)16;
final static byte MIN_PIN_SIZE = (byte)4;
// 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;
// pin is locked
final static short SW_CARD_IS_LOCKED = 0x6304;
final static short SW_NEW_PIN_TOO_LONG = 0x6307;
final static short SW_NEW_PIN_TOO_SHORT = 0x6308;
// 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 AppletWallet (byte[] bArray,short bOffset,byte bLength) {
// It is good programming practice to allocate
// all the memory that an applet needs during
// its lifetime inside the constructor
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 = new OwnerPIN(PIN_TRY_LIMIT, MAX_PIN_SIZE);
pin.update(bArray, (short)(bOffset + 1), aLen);
// Above command causes error.
register();
} // end of the constructor
public static void install(byte[] bArray, short bOffset, byte bLength) {
// create a Wallet applet instance
new AppletWallet(bArray, bOffset, bLength);
} // end of install method
public boolean select() {
// The applet declines to be selected
// if the pin is blocked.
if ( pin.getTriesRemaining() == 0 )
return false;
return true;
}// end of select method
public void deselect() {
// reset the pin value
pin.reset();
}
public void process(APDU apdu) {
// APDU object carries a byte array (buffer) to
// transfer incoming and outgoing APDU header
// and data bytes between card and CAD
// At this point, only the first header bytes
// [CLA, INS, P1, P2, P3] are available in
// the APDU buffer.
// The interface javacard.framework.ISO7816
// declares constants to denote the offset of
// these bytes in the APDU buffer
byte[] buffer = apdu.getBuffer();
// check SELECT APDU command
if (apdu.isISOInterindustryCLA()) {
if (buffer[ISO7816.OFFSET_INS] == (byte)(0xA4)) {
return;
} else {
ISOException.throwIt (ISO7816.SW_CLA_NOT_SUPPORTED);
}
}
// verify the reset of commands have the
// correct CLA byte, which specifies the
// command structure
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 CHANGE:
change(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 != 1 ) || (byteRead != 1) )
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
// get the credit amount
byte creditAmount = buffer[ISO7816.OFFSET_CDATA];
// 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);
} // end of deposit method
private void debit(APDU apdu) {
// access authentication
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);
// 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();
// inform system that the applet has finished
// processing the command and the system should
// now prepare to construct a response APDU
// which contains data field
short le = apdu.setOutgoing();
if ( le < 2 )
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
//informs the CAD the actual number of bytes
//returned
apdu.setOutgoingLength((byte)2);
// move the balance data into the APDU buffer
// starting at the offset 0
buffer[0] = (byte)(balance >> 8);
buffer[1] = (byte)(balance & 0xFF);
// send the 2-byte balance at the offset
// 0 in the apdu buffer
apdu.sendBytes((short)0, (short)4);
} // end of getBalance method
private void verify(APDU apdu) {
byte[] buffer = apdu.getBuffer();
if(pin.getTriesRemaining() == (byte)0)
ISOException.throwIt(SW_CARD_IS_LOCKED);
// retrieve the PIN data for validation.
byte byteRead = (byte)(apdu.setIncomingAndReceive());
// check pin
// the PIN data is read into the APDU buffer
// at the offset ISO7816.OFFSET_CDATA
// the PIN data length = byteRead
if ( pin.check(buffer, ISO7816.OFFSET_CDATA,
byteRead) == false )
ISOException.throwIt(SW_VERIFICATION_FAILED);
} // end of validate method
private void change(APDU apdu) {
byte[] buffer = apdu.getBuffer();
if(pin.getTriesRemaining() == (byte)0)
ISOException.throwIt(SW_CARD_IS_LOCKED);
if ( ! pin.isValidated() )
ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
// retrieve the PIN data for validation.
byte byteRead = (byte)(apdu.setIncomingAndReceive());
if(byteRead > MAX_PIN_SIZE)
ISOException.throwIt(SW_NEW_PIN_TOO_LONG);
if(byteRead < MIN_PIN_SIZE)
ISOException.throwIt(SW_NEW_PIN_TOO_SHORT);
pin.update(buffer, (short) ISO7816.OFFSET_CDATA, (byte)byteRead);
} // end of validate method
} // end of class Wallet
Last edited by
andromeda92 on Sun Aug 30, 2020 11:11 pm, edited 1 time in total.
-
kuafu
- Posts: 317
- Joined: Thu Jun 25, 2015 2:09 am
- Points :4559
-
Contact:
Post
by kuafu » Sun Aug 30, 2020 11:10 pm
You do not have the required permissions to view the files attached to this post. Please
login first.
well
-
andromeda92
- Posts: 38
- Joined: Tue Aug 18, 2020 6:08 pm
- Points :320
-
Contact:
Post
by andromeda92 » Sun Aug 30, 2020 11:13 pm
everything is working fine now. Thank you.
Users browsing this forum: No registered users and 32 guests
JavaCard OS : Disclaimer
Board Disclaimer
The views and comments posted in these fora are personal and do not necessarily represent the those of the Management of JavaCard OS.
The Management of JavaCard OS does not, under any circumstances whatsoever, accept any responsibility for any advice, or recommentations, made by, or implied by, any member or guest vistor of JavaCard OS that results in any loss whatsoever in any manner to a member of JavaCard OS, or to any other person.
Furthermore, the Management of JavaCard OS is not, and cannot be, responsible for the content of any other Internet site(s) that have been linked to from JavaCard OS.