begin application implementation

This commit is contained in:
Michele Balistreri 2017-09-25 12:26:15 +03:00
parent 360fa6ff5e
commit 6b600182dd
2 changed files with 67 additions and 9 deletions

View File

@ -5,12 +5,12 @@ Currently just a skeleton for the hardware wallet.
The .gpshell files are meant to be fed to GPShell. The statuswallet_install.gpshell file is actually dependent on the
target hw. Currently it assumes that the default VISA AID and keys for the ISD are used, but the version number is 2.
Other files will come and go until they are formalized as test scripts when we have a meaningful specification
and implementation.
The project is built using Gradle with the [Fidesmo Javacard Gradle plugin](https://github.com/fidesmo/gradle-javacard).
You can set the JavaCard HOME not only through the enviroment but also creating a gradle.properties file with the property
"com.fidesmo.gradle.javacard.home" set to the correct path
This implementation will try to use only features available in JavaCard 2.2.2 for broader compatibility with existing
## Implementation notes
* This implementation will try to use only features available in JavaCard 2.2.2 for broader compatibility with existing
hardware.
* The class byte of the APDU is not checked since there are nor conflicting INS code.

View File

@ -1,16 +1,32 @@
package im.status.wallet;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.*;
public class WalletApplet extends Applet {
static final byte INS_VERIFY_PIN = (byte) 0x20;
static final byte INS_CHANGE_PIN = (byte) 0x21;
static final byte INS_UNBLOCK_PIN = (byte) 0x22;
static final byte INS_LOAD_KEY = (byte) 0xD0;
static final byte INS_SIGN = (byte) 0xC0;
static final byte PIN_LENGTH = 6;
static final byte PIN_MAX_RETRIES = 3;
static final short TMP_BUFFER_LENGTH = 32;
private OwnerPIN ownerPIN;
private byte[] tmp;
public static void install(byte[] bArray, short bOffset, byte bLength) {
new WalletApplet(bArray, bOffset, bLength);
}
public WalletApplet(byte[] bArray, short bOffset, byte bLength) {
tmp = JCSystem.makeTransientByteArray(TMP_BUFFER_LENGTH, JCSystem.CLEAR_ON_DESELECT);
Util.arrayFillNonAtomic(tmp, (short) 0, PIN_LENGTH, (byte) 0x30);
ownerPIN = new OwnerPIN(PIN_MAX_RETRIES, PIN_LENGTH);
ownerPIN.update(tmp, (short) 0, PIN_LENGTH);
register(bArray, (short) (bOffset + 1), bArray[0]);
}
@ -20,6 +36,48 @@ public class WalletApplet extends Applet {
return;
}
byte[] apduBuffer = apdu.getBuffer();
switch(apduBuffer[ISO7816.OFFSET_INS]) {
case INS_VERIFY_PIN:
verifyPIN(apdu);
break;
case INS_CHANGE_PIN:
changePIN(apdu);
break;
case INS_UNBLOCK_PIN:
unblockPIN(apdu);
break;
case INS_LOAD_KEY:
loadKey(apdu);
break;
case INS_SIGN:
sign(apdu);
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
private void verifyPIN(APDU apdu) {
byte[] apduBuffer = apdu.getBuffer();
if (!ownerPIN.check(apduBuffer, ISO7816.OFFSET_CDATA, apduBuffer[ISO7816.OFFSET_LC])) {
ISOException.throwIt((short)((short) 0x63c0 | (short) ownerPIN.getTriesRemaining()));
}
}
private void changePIN(APDU apdu) {
}
private void unblockPIN(APDU apdu) {
}
private void loadKey(APDU apdu) {
}
private void sign(APDU apdu) {
}
}