From 551ac64fa7eb0f5dc03fd868d5f58d3f1ca18596 Mon Sep 17 00:00:00 2001 From: Manuel Thalmann Date: Tue, 24 Oct 2023 23:09:30 +0200 Subject: [PATCH] Allow sensitive commands only with PIN --- hwb1/src/hwb1/MyApplet.java | 102 +++++++++++++++++++++++------------- 1 file changed, 65 insertions(+), 37 deletions(-) diff --git a/hwb1/src/hwb1/MyApplet.java b/hwb1/src/hwb1/MyApplet.java index 8312b8f..6bd71a2 100644 --- a/hwb1/src/hwb1/MyApplet.java +++ b/hwb1/src/hwb1/MyApplet.java @@ -6,27 +6,37 @@ package hwb1; import javacard.framework.*; + /** * Applet class * * @author */ public class MyApplet extends Applet { + final static short SW_PIN_VERIFICATION_REQUIRED = 0x6301; final static byte PIN_TRY_LIMIT =(byte)0x03; final static byte MAX_PIN_SIZE =(byte)0x08; private byte[] authorName = new byte[] { 'M', 'a', 'n', 'u', 'e', 'l' }; private byte[] storage = new byte[] {}; - OwnerPIN pin; + private OwnerPIN pin; /** * 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 bLength the length in bytes of the parameter data in bArray */ - public static void install(byte[] bArray, short bOffset, byte bLength) { - new MyApplet(bArray, bOffset, bLength); + public static void install(byte[] buffer, short offset, byte length) { + 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 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.update(bArray, bOffset, bLength); + pin.update(appletData, dataOffset, dataLength); register(); } @@ -50,6 +60,11 @@ public class MyApplet extends Applet { } } + public void deselect() { + super.deselect(); + pin.reset(); + } + /** * Processes an incoming APDU. * @@ -66,44 +81,57 @@ public class MyApplet extends Applet { if (buffer[ISO7816.OFFSET_CLA] != (byte)0x80) { ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED); } else { + boolean authenticationRequired = false; byte instruction = buffer[ISO7816.OFFSET_INS]; switch (instruction) { - case 0x00: - case 0x04: - byte[] response; - length = apdu.setOutgoing(); + case 0x04: + case 0x02: + authenticationRequired = !pin.isValidated(); + break; + } - if (instruction == 0x00) { - response = authorName; - length = (short)response.length; - } else { - response = storage; + if (authenticationRequired) { + ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED); + } + else { + switch (instruction) { + case 0x00: + case 0x04: + byte[] response; + length = apdu.setOutgoing(); - if (length > response.length) { - ISOException.throwIt((short)(ISO7816.SW_CORRECT_LENGTH_00 | response.length)); - } - } + if (instruction == 0x00) { + response = authorName; + length = (short)response.length; + } else { + response = storage; - apdu.setOutgoingLength(length); - apdu.sendBytesLong(response, (short) 0, length); - break; - case 0x02: - length = apdu.setIncomingAndReceive(); - storage = new byte[length]; + if (length > response.length) { + ISOException.throwIt((short)(ISO7816.SW_CORRECT_LENGTH_00 | response.length)); + } + } - if (length > 20) { - ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); - } else { - Util.arrayCopy(buffer, ISO7816.OFFSET_CDATA, storage, (short) 0, length); - } - break; - case 0x20: - length = apdu.setIncomingAndReceive(); - pin.check(buffer, (short) ISO7816.OFFSET_CDATA, (byte)length); - default: - ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); - break; + apdu.setOutgoingLength(length); + apdu.sendBytesLong(response, (short) 0, length); + break; + case 0x02: + length = apdu.setIncomingAndReceive(); + storage = new byte[length]; + + if (length > 20) { + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); + } else { + Util.arrayCopy(buffer, ISO7816.OFFSET_CDATA, storage, (short) 0, length); + } + 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);