Re: Video Tutorial - How to download CAP file to smart card?
Posted: Thu May 25, 2017 12:21 pm
Hi i have the problem that i cant upload my Applet to the Smartcard (NXP J3A081) and the Card is Empty but when i try Download i get the message:"6A 80"
The Code is:
and the other class is:
when i build the Code there is no error only one warning: warning: This package requires int support. But nothing else.
The Code is:
Code: Select all
package pwSafe;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.APDU;
import javacard.framework.JCSystem;
import javacard.framework.Util;
import javacard.framework.OwnerPIN;
import javacard.security.RandomData;
public class pwSafe extends Applet
{
final static byte CLA_NUMBER = (byte) 0x80;
final static byte INS_INIT = (byte) 0x10;
final static byte INS_CHANGE_PIN = (byte) 0x11;
final static byte INS_PIN_VERIFY = (byte) 0x12;
final static byte INS_CREATE_FILE = (byte) 0xE0;
final static byte INS_UPDATE_BINARY = (byte) 0xD6;
final static byte INS_READ_BINARY = (byte) 0xB0;
final static byte INS_DELETE_FILE = (byte) 0xE4;
//Variables for the PIN
private final static byte PIN_MAX_TRIES = (byte) 3;
private final static byte PIN_MIN_LENGTH = (byte) 4;
private final static byte PIN_MAX_LENGTH = (byte) 16;
//Variables for the PUK
private final static byte PUK_MAX_TRIES = (byte) 5;
private final static byte PUK_LENGTH = (byte) 12;
private static final byte STATE_INIT = (byte) 0x00;
private static final byte STATE_SECURE_NO_DATA = (byte) 0x01;
private static final byte STATE_SECURE_DATA = (byte) 0x05;
// Status words:
public static final short SW_PIN_TRIES_REMAINING = (short)0x63C0;
public static final short SW_COMMAND_NOT_ALLOWED_GENERAL = (short)0x6900;
private byte state;
private OwnerPIN pin = null;
private OwnerPIN puk = null;
private RandomData randomKey;
private fileSystem fileClass;
public static void install(byte[] buffer, short offset, byte length) {
new pwSafe();
}
protected pwSafe() {
pin = new OwnerPIN(PIN_MAX_TRIES, PIN_MAX_LENGTH);
puk = new OwnerPIN(PUK_MAX_TRIES, PUK_LENGTH);
fileClass = new fileSystem();
//Set state and write to file
state = STATE_INIT;
randomKey = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM);
register();
}
public boolean select() {
return true;
}
public void deselect() {
pin.reset();
puk.reset();
}
public void process(APDU apdu) {
byte buffer[] = apdu.getBuffer();
byte cla = buffer[ISO7816.OFFSET_CLA];
byte ins = buffer[ISO7816.OFFSET_INS];
if(cla == CLA_NUMBER) {
switch (ins)
{
//Personal Data
//INS = 0x10
case INS_INIT:
cardINIT(apdu);
break;
//INS = 0x11
case INS_CHANGE_PIN:
changePIN(apdu);
break;
//INS = 0x12
case INS_PIN_VERIFY:
checkPIN(apdu);
break;
//Storage Data
//INS = 0xE0
case INS_CREATE_FILE:
createFile(apdu);
break;
//INS = 0xD6
case INS_UPDATE_BINARY:
break;
//INS = 0xB0
case INS_READ_BINARY:
break;
//INS = 0xE4
case INS_DELETE_FILE:
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
} else {
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
}
//CLA = 0x80; INS = 0x10; P1 = 0x00; P2 = 0x01
private void cardINIT(APDU apdu) throws ISOException {
byte[] buf = apdu.getBuffer();
byte p1 = buf[ISO7816.OFFSET_P1];
byte p2 = buf[ISO7816.OFFSET_P2];
short offset_cdata;
short lc;
//Check lenght field
lc = apdu.setIncomingAndReceive();
if(lc != apdu.getIncomingLength()) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
//Get the Offset of the Data
offset_cdata = apdu.getOffsetCdata();
//Check if the State is correct
if(state != STATE_INIT) {
ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
}
if(p1 != (byte)0x00 && p2 != (byte)0x01) {
ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
}
if(lc > PIN_MAX_LENGTH || lc < PIN_MIN_LENGTH) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
Util.arrayFillNonAtomic(buf, (short)(offset_cdata + lc), (short)(PIN_MAX_LENGTH - lc), (byte) 0x00);
pin.update(buf, offset_cdata, PIN_MAX_LENGTH);
pin.resetAndUnblock();
generatePUKKey(apdu);
}
//Verify PIN
//CLA = 0x80; INS = 0x12; P1 = 0x01; P2 = 0x00; Data = PIN
private void checkPIN(APDU apdu) throws ISOException {
byte[] buf = apdu.getBuffer();
byte p1 = buf[ISO7816.OFFSET_P1];
byte p2 = buf[ISO7816.OFFSET_P2];
short offset_cdata;
short lc;
//Check lenght field
lc = apdu.setIncomingAndReceive();
if(lc != apdu.getIncomingLength()) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
//Get the Offset of the Data
offset_cdata = apdu.getOffsetCdata();
//Check if the State is correct
if(state == STATE_SECURE_NO_DATA || state == STATE_SECURE_DATA) {
ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
}
if(p1 != (byte)0x01 && p2 != (byte)0x00) {
ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
}
Util.arrayFillNonAtomic(buf, (short)(offset_cdata + lc), (short)(PIN_MAX_LENGTH - lc), (byte) 0x00);
if(! pin.check(buf, offset_cdata, PIN_MAX_LENGTH)) {
ISOException.throwIt((short)(SW_PIN_TRIES_REMAINING | pin.getTriesRemaining()));
}
}
//Change PIN
//CLA = 0x80; INS = 0x11; P1 = 0x00; P2 = 0x02;Data = PUK + PIN
private void changePIN(APDU apdu) throws ISOException {
byte[] buf = apdu.getBuffer();
byte p1 = buf[ISO7816.OFFSET_P1];
byte p2 = buf[ISO7816.OFFSET_P2];
short offset_cdata;
short lc;
if(! pin.isValidated()){
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
}
//Check lenght field
lc = apdu.setIncomingAndReceive();
if(lc != apdu.getIncomingLength()) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
//Get the Offset of the Data
offset_cdata = apdu.getOffsetCdata();
//Check if the State is correct
if(state == STATE_SECURE_NO_DATA || state == STATE_SECURE_DATA) {
ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
}
if(p1 != (byte)0x00 && p2 != (byte)0x02) {
ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
}
if(! puk.check(buf, offset_cdata, PUK_LENGTH)) {
ISOException.throwIt((short)(SW_PIN_TRIES_REMAINING | puk.getTriesRemaining()));
}
if( (lc - (offset_cdata + PUK_LENGTH)) < PIN_MIN_LENGTH || (lc - (offset_cdata + PUK_LENGTH) > PIN_MAX_LENGTH)) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
Util.arrayFillNonAtomic(buf, (short)(offset_cdata + lc), (short)(PIN_MAX_LENGTH - (lc - PUK_LENGTH)), (byte) 0x00);
pin.update(buf, (short)(offset_cdata + PUK_LENGTH), PIN_MAX_LENGTH);
}
private void generatePUKKey(APDU apdu) throws ISOException {
byte[] buf = apdu.getBuffer();
randomKey.generateData(buf, (short) 0, PUK_LENGTH);
puk.update(buf, (short)0, PUK_LENGTH);
puk.resetAndUnblock();
apdu.setOutgoingLength(PUK_LENGTH);
apdu.sendBytes((short)0, PUK_LENGTH);
}
private void createFile(APDU apdu) {
byte[] buf = apdu.getBuffer();
byte p1 = buf[ISO7816.OFFSET_P1];
byte p2 = buf[ISO7816.OFFSET_P2];
short offset_cdata;
short fileID = (short)0x0000;
byte[] fileSize = null;
offset_cdata = apdu.getOffsetCdata();
Util.arrayCopy(buf, offset_cdata, fileSize, (short)0, (short)2 );
if(p1 == (byte)0x01) {
fileID = (short)0x0100;
} else if(p1 == (byte)0x02){
fileID = (short)0x0101;
}
fileClass.createFile(fileID, Util.makeShort(fileSize[(byte)0], fileSize[(byte)1]));
}
}
and the other class is:
Code: Select all
package pwSafe;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.Util;
public class fileSystem {
private Object[] listFiles;
private short[] listfileSizes;
public static final short keepassData1 = (short)0x0100;
public static final short keepassData2 = (short)0x0101;
private static final short keepassData_Index1 = (short)0x0001;
private static final short keepassData_Index2 = (short)0x0002;
public fileSystem() {
listFiles = new Object[(short)2];
listfileSizes = new short[(short)2];
}
public void createFile(short fileID, short fileSize) {
short index = getFileIndex(fileID);
if(listFiles[index] == null) {
listFiles[index] = new byte[fileSize];
}
listfileSizes[index] = fileSize;
}
public void writeDataToFile(short fileID, short fileOffset, byte[] fileData, short dataLength) {
short selFileSize = getFileSize(fileID);
if (selFileSize < (fileOffset + dataLength)) {
ISOException.throwIt(ISO7816.SW_FILE_FULL);
}
Util.arrayCopy(fileData, (short)0, getFile(fileID), fileOffset, dataLength);
}
public byte[] readDataFromFile(short fileID, short fileOffset, short length) {
short selFileSize = getFileSize(fileID);
byte[] data = null;
if((fileOffset + length) > selFileSize) {
Util.arrayCopy(getFile(fileID), fileOffset, data, (short)0, (short)(selFileSize - fileOffset));
} else {
Util.arrayCopy(getFile(fileID), fileOffset, data, (short)0, length);
}
return (byte[])data;
}
private short getFileIndex(short fileID) {
if(fileID == keepassData1) {
return keepassData_Index1;
} else if (fileID == keepassData2) {
return keepassData_Index2;
} else {
return (short)-1;
}
}
private byte[] getFile(short fileID) {
short index = getFileIndex(fileID);
if(index == -1) {
return null;
}
return (byte[]) listFiles[index];
}
private short getFileSize(short fileID) {
short index = getFileIndex(fileID);
if(index == (short)-1) {
return (short)-1;
}
return listfileSizes[index];
}
}
when i build the Code there is no error only one warning: warning: This package requires int support. But nothing else.