From 6b600182dd1923333c485577b5b7d4b1bdacd069 Mon Sep 17 00:00:00 2001 From: Michele Balistreri Date: Mon, 25 Sep 2017 12:26:15 +0300 Subject: [PATCH] begin application implementation --- README.md | 10 +-- .../java/im/status/wallet/WalletApplet.java | 66 +++++++++++++++++-- 2 files changed, 67 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 276b9ee..4c36efa 100644 --- a/README.md +++ b/README.md @@ -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 -hardware. \ No newline at end of file +## 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. \ No newline at end of file diff --git a/src/main/java/im/status/wallet/WalletApplet.java b/src/main/java/im/status/wallet/WalletApplet.java index c120fcc..257eb38 100644 --- a/src/main/java/im/status/wallet/WalletApplet.java +++ b/src/main/java/im/status/wallet/WalletApplet.java @@ -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) { + } }