Compare commits

...

6 commits

2 changed files with 80 additions and 62 deletions

View file

@ -6,6 +6,9 @@ card_connect
// select // select
send_apdu -sc 0 -APDU 00A40400080102030405060809 send_apdu -sc 0 -APDU 00A40400080102030405060809
// Public Command
send_apdu -sc 0 -APDU 80000000
// Locked Commands // Locked Commands
send_apdu -sc 0 -APDU 8002000002FFFE send_apdu -sc 0 -APDU 8002000002FFFE
@ -13,14 +16,14 @@ send_apdu -sc 0 -APDU 8002000002FFFE
send_apdu -sc 0 -APDU 802000000431313131 send_apdu -sc 0 -APDU 802000000431313131
// Still Locked Commands // Still Locked Commands
send_apdu -sc 0 -APDU 800400000001 send_apdu -sc 0 -APDU 8004000000
// Unlock Card With Correct PIN // Unlock Card With Correct PIN
send_apdu -sc 0 -APDU 802000000431323334 send_apdu -sc 0 -APDU 802000000431323334
// Now Unlocked Commands // Now Unlocked Commands
send_apdu -sc 0 -APDU 8002000002FFFE send_apdu -sc 0 -APDU 8002000002FFFE
send_apdu -sc 0 -APDU 800400000001 send_apdu -sc 0 -APDU 8004000001
// Query Author Name // Query Author Name
send_apdu -sc 0 -APDU 80000000 send_apdu -sc 0 -APDU 80000000
@ -29,8 +32,8 @@ send_apdu -sc 0 -APDU 80000000
send_apdu -sc 0 -APDU 8002000002FFFE send_apdu -sc 0 -APDU 8002000002FFFE
// Querying Data // Querying Data
send_apdu -sc 0 -APDU 800400000001 send_apdu -sc 0 -APDU 8004000001
send_apdu -sc 0 -APDU 800400000002 send_apdu -sc 0 -APDU 8004000002
// Triggering Unsupported Instruction Error // Triggering Unsupported Instruction Error
send_apdu -sc 0 -APDU 8001000000 send_apdu -sc 0 -APDU 8001000000
@ -43,7 +46,22 @@ send_apdu -sc 0 -APDU 80020000150102030405060708090A0B0C0D0E0F101112131415
// Querying Incorrect Amount of Bytes // Querying Incorrect Amount of Bytes
send_apdu -sc 0 -APDU 8002000002FFFE send_apdu -sc 0 -APDU 8002000002FFFE
send_apdu -sc 0 -APDU 800400000003 send_apdu -sc 0 -APDU 8004000003
// De- and re-select applet
card_disconnect
card_connect
send_apdu -sc 0 -APDU 00A40400080102030405060809
// Exceed maximum of PIN unlock trials
send_apdu -sc 0 -APDU 802000000431313131
send_apdu -sc 0 -APDU 802000000431313131
send_apdu -sc 0 -APDU 802000000431313131
// De- and re-select applet in locked state
card_disconnect
card_connect
send_apdu -sc 0 -APDU 00A40400080102030405060809
card_disconnect card_disconnect
release_context release_context

View file

@ -14,6 +14,7 @@ import javacard.framework.*;
*/ */
public class MyApplet extends Applet { public class MyApplet extends Applet {
final static short SW_PIN_VERIFICATION_REQUIRED = 0x6301; final static short SW_PIN_VERIFICATION_REQUIRED = 0x6301;
final static short SW_VERIFICATION_FAILED = 0x6300;
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' };
@ -28,13 +29,13 @@ public class MyApplet extends Applet {
* @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[] buffer, short offset, byte length) { public static void install(byte[] buffer, short offset, byte length) {
byte aidLength = buffer[offset]; byte aidLength = buffer[offset];
short controlInfoOffset = (short)(offset + 1 + aidLength); short controlInfoOffset = (short)(offset + 1 + aidLength);
byte controlInfoLength = buffer[controlInfoOffset]; byte controlInfoLength = buffer[controlInfoOffset];
short dataOffset = (short)(controlInfoOffset + 1 + controlInfoLength); short dataOffset = (short)(controlInfoOffset + 1 + controlInfoLength);
byte dataLength = buffer[dataOffset]; byte dataLength = buffer[dataOffset];
new MyApplet(buffer, (short)(dataOffset + 1), dataLength); new MyApplet(buffer, (short)(dataOffset + 1), dataLength);
} }
@ -52,17 +53,9 @@ public class MyApplet extends Applet {
register(); register();
} }
public boolean select() {
if (pin.getTriesRemaining() == 0) {
return false;
} else {
return super.select();
}
}
public void deselect() { public void deselect() {
super.deselect(); super.deselect();
pin.reset(); pin.reset();
} }
/** /**
@ -76,63 +69,70 @@ public class MyApplet extends Applet {
byte[] buffer = apdu.getBuffer(); byte[] buffer = apdu.getBuffer();
if (selectingApplet()) { if (selectingApplet()) {
ISOException.throwIt(ISO7816.SW_NO_ERROR); if (pin.getTriesRemaining() == 0) {
ISOException.throwIt(SW_VERIFICATION_FAILED);
} else {
ISOException.throwIt(ISO7816.SW_NO_ERROR);
}
} else { } else {
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; boolean authenticationRequired = false;
byte instruction = buffer[ISO7816.OFFSET_INS]; byte instruction = buffer[ISO7816.OFFSET_INS];
switch (instruction) { switch (instruction) {
case 0x04: case 0x02:
case 0x02: case 0x04:
authenticationRequired = !pin.isValidated(); authenticationRequired = !pin.isValidated();
break; break;
} }
if (authenticationRequired) { if (authenticationRequired) {
ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED); ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
} }
else { else {
switch (instruction) { switch (instruction) {
case 0x00: case 0x00:
case 0x04: case 0x04:
byte[] response; byte[] response;
length = apdu.setOutgoing(); length = apdu.setOutgoing();
if (instruction == 0x00) { if (instruction == 0x00) {
response = authorName; response = authorName;
length = (short)response.length; length = (short)response.length;
} else { } else {
response = storage; response = storage;
if (length > response.length) { if (length > response.length) {
ISOException.throwIt((short)(ISO7816.SW_CORRECT_LENGTH_00 | response.length)); ISOException.throwIt((short)(ISO7816.SW_CORRECT_LENGTH_00 | response.length));
} }
} }
apdu.setOutgoingLength(length); apdu.setOutgoingLength(length);
apdu.sendBytesLong(response, (short) 0, 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);
break; break;
default: case 0x02:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); length = apdu.setIncomingAndReceive();
break; 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();
if (!pin.check(buffer, (short) ISO7816.OFFSET_CDATA, (byte)length)) {
ISOException.throwIt(SW_VERIFICATION_FAILED);
}
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
break;
}
} }
ISOException.throwIt(ISO7816.SW_NO_ERROR); ISOException.throwIt(ISO7816.SW_NO_ERROR);