Allow sensitive commands only with PIN

This commit is contained in:
Manuel Thalmann 2023-10-24 23:09:30 +02:00
parent de7ada08c9
commit 551ac64fa7

View file

@ -6,27 +6,37 @@
package hwb1; package hwb1;
import javacard.framework.*; import javacard.framework.*;
/** /**
* Applet class * Applet class
* *
* @author <user> * @author <user>
*/ */
public class MyApplet extends Applet { public class MyApplet extends Applet {
final static short SW_PIN_VERIFICATION_REQUIRED = 0x6301;
final static byte PIN_TRY_LIMIT =(byte)0x03; final static byte PIN_TRY_LIMIT =(byte)0x03;
final static byte MAX_PIN_SIZE =(byte)0x08; final static byte MAX_PIN_SIZE =(byte)0x08;
private byte[] authorName = new byte[] { 'M', 'a', 'n', 'u', 'e', 'l' }; private byte[] authorName = new byte[] { 'M', 'a', 'n', 'u', 'e', 'l' };
private byte[] storage = new byte[] {}; private byte[] storage = new byte[] {};
OwnerPIN pin; private OwnerPIN pin;
/** /**
* Installs this applet. * Installs this applet.
* *
* @param bArray the array containing installation parameters * @param buffer the array containing installation parameters
* @param bOffset the starting offset in bArray * @param bOffset the starting offset in bArray
* @param bLength the length in bytes of the parameter data in bArray * @param bLength the length in bytes of the parameter data in bArray
*/ */
public static void install(byte[] bArray, short bOffset, byte bLength) { public static void install(byte[] buffer, short offset, byte length) {
new MyApplet(bArray, bOffset, bLength); byte aidLength = buffer[offset];
short controlInfoOffset = (short)(offset + 1 + aidLength);
byte controlInfoLength = buffer[controlInfoOffset];
short dataOffset = (short)(controlInfoOffset + 1 + controlInfoLength);
byte dataLength = buffer[dataOffset];
new MyApplet(buffer, (short)(dataOffset + 1), dataLength);
} }
/** /**
@ -36,9 +46,9 @@ public class MyApplet extends Applet {
* @param bOffset the starting offset in bArray * @param bOffset the starting offset in bArray
* @param bLength the length in bytes of the parameter data in bArray * @param bLength the length in bytes of the parameter data in bArray
*/ */
protected MyApplet(byte[] bArray, short bOffset, byte bLength) { protected MyApplet(byte[] appletData, short dataOffset, byte dataLength) {
pin = new OwnerPIN(PIN_TRY_LIMIT, MAX_PIN_SIZE); pin = new OwnerPIN(PIN_TRY_LIMIT, MAX_PIN_SIZE);
pin.update(bArray, bOffset, bLength); pin.update(appletData, dataOffset, dataLength);
register(); register();
} }
@ -50,6 +60,11 @@ public class MyApplet extends Applet {
} }
} }
public void deselect() {
super.deselect();
pin.reset();
}
/** /**
* Processes an incoming APDU. * Processes an incoming APDU.
* *
@ -66,44 +81,57 @@ public class MyApplet extends Applet {
if (buffer[ISO7816.OFFSET_CLA] != (byte)0x80) { if (buffer[ISO7816.OFFSET_CLA] != (byte)0x80) {
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED); ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
} else { } else {
boolean authenticationRequired = false;
byte instruction = buffer[ISO7816.OFFSET_INS]; byte instruction = buffer[ISO7816.OFFSET_INS];
switch (instruction) { switch (instruction) {
case 0x00: case 0x04:
case 0x04: case 0x02:
byte[] response; authenticationRequired = !pin.isValidated();
length = apdu.setOutgoing(); break;
}
if (instruction == 0x00) { if (authenticationRequired) {
response = authorName; ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
length = (short)response.length; }
} else { else {
response = storage; switch (instruction) {
case 0x00:
case 0x04:
byte[] response;
length = apdu.setOutgoing();
if (length > response.length) { if (instruction == 0x00) {
ISOException.throwIt((short)(ISO7816.SW_CORRECT_LENGTH_00 | response.length)); response = authorName;
} length = (short)response.length;
} } else {
response = storage;
apdu.setOutgoingLength(length); if (length > response.length) {
apdu.sendBytesLong(response, (short) 0, length); ISOException.throwIt((short)(ISO7816.SW_CORRECT_LENGTH_00 | response.length));
break; }
case 0x02: }
length = apdu.setIncomingAndReceive();
storage = new byte[length];
if (length > 20) { apdu.setOutgoingLength(length);
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); apdu.sendBytesLong(response, (short) 0, length);
} else { break;
Util.arrayCopy(buffer, ISO7816.OFFSET_CDATA, storage, (short) 0, length); case 0x02:
} length = apdu.setIncomingAndReceive();
break; storage = new byte[length];
case 0x20:
length = apdu.setIncomingAndReceive(); if (length > 20) {
pin.check(buffer, (short) ISO7816.OFFSET_CDATA, (byte)length); ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
default: } else {
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); Util.arrayCopy(buffer, ISO7816.OFFSET_CDATA, storage, (short) 0, length);
break; }
break;
case 0x20:
length = apdu.setIncomingAndReceive();
pin.check(buffer, (short) ISO7816.OFFSET_CDATA, (byte)length);
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
break;
}
} }
ISOException.throwIt(ISO7816.SW_NO_ERROR); ISOException.throwIt(ISO7816.SW_NO_ERROR);