diff --git a/APPLICATION.MD b/APPLICATION.MD index 9a7845a..f2b0f56 100644 --- a/APPLICATION.MD +++ b/APPLICATION.MD @@ -109,7 +109,7 @@ always returns 0x63C0, even if the PUK is inserted correctly. In this case the w * P1 = 0x01 (ECC SECP256k1 keypair) * P2 = 0x00 * Data = the key data -* Response SW = 0x9000 on success, 0x6A80 if the format is invalid +* Response SW = 0x9000 on success, 0x6A80 if the format is invalid, 0x6A86 if P1 is invalid * Preconditions: Secure Channel must be opened, user PIN must be verified At the moment P1 can only be 0x01, but new key types could be added later. The ECC SECP256k1 keypair is diff --git a/src/main/java/im/status/wallet/WalletApplet.java b/src/main/java/im/status/wallet/WalletApplet.java index e62601c..82088d6 100644 --- a/src/main/java/im/status/wallet/WalletApplet.java +++ b/src/main/java/im/status/wallet/WalletApplet.java @@ -17,6 +17,8 @@ public class WalletApplet extends Applet { static final short EC_KEY_SIZE = 256; + static final byte LOAD_KEY_EC = 0x01; + static final byte TLV_KEY_TEMPLATE = (byte) 0xA1; static final byte TLV_PUB_KEY = (byte) 0x80; static final byte TLV_PRIV_KEY = (byte) 0x81; @@ -27,6 +29,7 @@ public class WalletApplet extends Applet { private ECPublicKey publicKey; private ECPrivateKey privateKey; private Signature signature; + private boolean signInProgress; public static void install(byte[] bArray, short bOffset, byte bLength) { new WalletApplet(bArray, bOffset, bLength); @@ -51,6 +54,7 @@ public class WalletApplet extends Applet { ECCurves.setSECP256K1CurveParameters(privateKey); signature = Signature.getInstance(Signature.ALG_ECDSA_SHA, false); + signInProgress = false; register(bArray, (short) (bOffset + 1), bArray[bOffset]); } @@ -160,6 +164,11 @@ public class WalletApplet extends Applet { } byte[] apduBuffer = apdu.getBuffer(); + + if (apduBuffer[ISO7816.OFFSET_P1] != LOAD_KEY_EC) { + ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); + } + secureChannel.decryptAPDU(apduBuffer); short pubOffset = (short)(ISO7816.OFFSET_CDATA + 2); @@ -180,7 +189,7 @@ public class WalletApplet extends Applet { JCSystem.commitTransaction(); - signature.init(privateKey, Signature.MODE_SIGN); + signInProgress = false; } private void sign(APDU apdu) { @@ -189,6 +198,9 @@ public class WalletApplet extends Applet { if (!(secureChannel.isOpen() && pin.isValidated() && privateKey.isInitialized())) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } + + //signature.init(privateKey, Signature.MODE_SIGN); + } private boolean allDigits(byte[] buffer, short off, short len) { diff --git a/src/test/java/im/status/wallet/WalletAppletCommandSet.java b/src/test/java/im/status/wallet/WalletAppletCommandSet.java index f14c7fb..c1c4a95 100644 --- a/src/test/java/im/status/wallet/WalletAppletCommandSet.java +++ b/src/test/java/im/status/wallet/WalletAppletCommandSet.java @@ -71,11 +71,11 @@ public class WalletAppletCommandSet { data[5 + publicKey.length] = (byte) privLen; System.arraycopy(privateKey, privOff, data, 6 + publicKey.length, privLen); - return loadKey(data); + return loadKey(data, WalletApplet.LOAD_KEY_EC); } - public ResponseAPDU loadKey(byte[] data) throws CardException { - CommandAPDU loadKey = new CommandAPDU(0x80, WalletApplet.INS_LOAD_KEY, 0, 0, secureChannel.encryptAPDU(data)); + public ResponseAPDU loadKey(byte[] data, byte keyType) throws CardException { + CommandAPDU loadKey = new CommandAPDU(0x80, WalletApplet.INS_LOAD_KEY, keyType, 0, secureChannel.encryptAPDU(data)); return apduChannel.transmit(loadKey); } } diff --git a/src/test/java/im/status/wallet/WalletAppletTest.java b/src/test/java/im/status/wallet/WalletAppletTest.java index 3d40be6..cb0b35e 100644 --- a/src/test/java/im/status/wallet/WalletAppletTest.java +++ b/src/test/java/im/status/wallet/WalletAppletTest.java @@ -204,13 +204,16 @@ public class WalletAppletTest { response = cmdSet.verifyPIN("000000"); assertEquals(0x9000, response.getSW()); - response = cmdSet.loadKey(new byte[] { (byte) 0xAA, 0x02, (byte) 0x80, 0x00}); + response = cmdSet.loadKey(new byte[] { (byte) 0xAA, 0x02, (byte) 0x80, 0x00}, (byte) 0x00); + assertEquals(0x6A86, response.getSW()); + + response = cmdSet.loadKey(new byte[] { (byte) 0xAA, 0x02, (byte) 0x80, 0x00}, WalletApplet.LOAD_KEY_EC); assertEquals(0x6A80, response.getSW()); - response = cmdSet.loadKey(new byte[] { (byte) 0xA1, 0x02, (byte) 0x80, 0x00}); + response = cmdSet.loadKey(new byte[] { (byte) 0xA1, 0x02, (byte) 0x80, 0x00}, WalletApplet.LOAD_KEY_EC); assertEquals(0x6A80, response.getSW()); - response = cmdSet.loadKey(new byte[] { (byte) 0xA1, 0x06, (byte) 0x80, 0x01, 0x01, (byte) 0x81, 0x01, 0x02}); + response = cmdSet.loadKey(new byte[] { (byte) 0xA1, 0x06, (byte) 0x80, 0x01, 0x01, (byte) 0x81, 0x01, 0x02}, WalletApplet.LOAD_KEY_EC); assertEquals(0x6A80, response.getSW()); response = cmdSet.loadKey(keyPair);