diff --git a/APPLICATION.MD b/APPLICATION.MD index 9266e7b..9f18555 100644 --- a/APPLICATION.MD +++ b/APPLICATION.MD @@ -1,4 +1,4 @@ -# Status Wallet Application +# Status Keycard Application ## Version diff --git a/CLIENT_NOTES.md b/CLIENT_NOTES.md index f46218d..58c3b8e 100644 --- a/CLIENT_NOTES.md +++ b/CLIENT_NOTES.md @@ -1,11 +1,10 @@ # Notes for client implementation -This document should help client application developers to integrate support for the hardware wallet in their -applications. +This document should help client application developers to integrate support for the Status Keycard in their applications. ## Low-level communication -The hardware wallet is a JavaCard application and as such is deployed on ISO7816 compatible SmartCards. Communication +The Status Keycard is a JavaCard application and as such is deployed on ISO7816 compatible SmartCards. Communication will happen exchanging APDUs using either the T=0 or preferably the T=1 protocol. Most operating systems use an implementation of [this Microsoft API](https://msdn.microsoft.com/en-us/library/windows/desktop/aa374731(v=vs.85).aspx#smart_card_functions) like [PCSC lite](http://pcsclite.alioth.debian.org/pcsclite.html). Your language of choice might provide bindings for @@ -18,18 +17,18 @@ A few things to keep in mind when communicating with SmartCards messing with the card while you are using it. 3. A SmartCard can have multiple applications installed. If using only the basic channel (recommended for our use-case) only a single application can be selected at the time. This must be done explicitly on each reset by issuing the - SELECT command with the AID of the wallet application. + SELECT command with the AID of the keycard application. 4. Since we are not using extended APDUs, the maximum size of the data field of the APDU is 255 bytes. ## Wallet management and security -Before thinking about the application-specific communication (i.e: actually using the wallet applet to derive keys and +Before thinking about the application-specific communication (i.e: actually using the Keycard applet to derive keys and sign transactions) the client must be able to actually talk with the card using its [Secure Channel protocol](SECURE_CHANNEL.MD). -The first step, after an APDU channel is available is to [SELECT](APPLICATION.MD) the wallet application on the card. -The wallet will return its Instance UID and public key for Secure Channel establishment. Although both values are unique, -only use the Instance UID to identify the wallet since only this value is guaranteed not to change over the lifetime of -the card. If your application has already performed pairing with the wallet with this Instance UID, you can establish +The first step, after an APDU channel is available is to [SELECT](APPLICATION.MD) the Keycard application on the card. +The Keycard will return its Instance UID and public key for Secure Channel establishment. Although both values are unique, +only use the Instance UID to identify the Keycard since only this value is guaranteed not to change over the lifetime of +the card. If your application has already performed pairing with the Keycard with this Instance UID, you can establish a Secure Channel session (described later). Otherwise you should proceed with pairing. For pairing, the client must show that it knows the pairing code. For this reason the user must be prompted @@ -71,10 +70,10 @@ the user has been authenticated or not in order to avoid repeatedly asking for t error to any APDU requiring user authentication if the user has not been authenticated in the current application session. -## Wallet features and workflow +## Keycard features and workflow Now that the client can finally talk with the applet and provide user authentication facilities, it is time to look on -how to actually use the wallet. The wallet applet allows management of a single HD wallet as described in the +how to actually use the Keycard. The Keycard applet allows management of a single HD wallet as described in the [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) specifications. It provides the following features 1. Source of entropy to generate master seeds (GENERATE MNEMONIC). No PIN required (has no effect on card state). @@ -136,5 +135,5 @@ must use DERIVE KEY before exporting the desired key. key derivation, but you shouldn't use it because, as explained above, it wouldn't work on the card. 5. If using jCardSim, only use our fork, since some of the needed algorithms are unsupported in the upstream version. 6. The pairing code is a randomly generated password (using whatever password generation algorithm is desired). This -password must be converted to a 256-bit key using PBKDF2 with the salt "Status Hardware Wallet Lite" and 50000 iterations. +password must be converted to a 256-bit key using PBKDF2 with the salt "Keycard Pairing Password Salt" and 50000 iterations. diff --git a/README.md b/README.md index 768d129..146e709 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,4 @@ -# JavaCard Hardware Wallet - -The status.im Hardware Wallet. At the moment Secure Channel and PIN management/verification are implemented. +# Status Keycard 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 environment but also creating a gradle.properties file with the @@ -15,7 +13,7 @@ installed on the system. The gradle.properties file must contain the following p * im.status.gradle.gpshell.enc_key = the ENC key for the ISD * im.status.gradle.gpshell.kek_key = the KEK key for the ISD * im.status.gradle.gpshell.kvn = the Key Version Number for the ISD -* im.status.wallet.test.simulated = true if the test should run on the simulator, false (or anything else) otherwise +* im.status.keycard.test.simulated = true if the test should run on the simulator, false (or anything else) otherwise Testing is done with JUnit and performed either on a real card or on [jCardSim](https://github.com/status-im/jcardsim). Although the tests are comprehensive, debugging on the real card is not easy because raw APDUs are not shown in the test @@ -23,7 +21,7 @@ log and there is no way to set breakpoints in the applet. In order to test with the simulator with an IDE, you need to pass these additional parameters to the JVM -```-noverify -Dim.status.wallet.test.simulated=true``` +```-noverify -Dim.status.keycard.test.simulated=true``` ## Compilation 1. Download and install the JavaCard 3.0.4 SDK from [Oracle](http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-javame-419430.html#java_card_kit-classic-3_0_4-rr-bin-do) @@ -52,7 +50,7 @@ im.status.gradle.gpshell.mac_key=404142434445464748494a4b4c4d4e4f im.status.gradle.gpshell.enc_key=404142434445464748494a4b4c4d4e4f im.status.gradle.gpshell.kek_key=404142434445464748494a4b4c4d4e4f im.status.gradle.gpshell.kvn=0 -im.status.wallet.test.simulated=false +im.status.keycard.test.simulated=false ``` ## Implementation notes diff --git a/UX_NOTES.md b/UX_NOTES.md index 46eb81d..3abfb03 100644 --- a/UX_NOTES.md +++ b/UX_NOTES.md @@ -1,6 +1,6 @@ -# Status Wallet UX guidelines +# Status Keycard UX guidelines -The scope of this document is to describe the interactions between the hardware wallet, the user and client applications. +The scope of this document is to describe the interactions between the keycard, the user and client applications. Technical details about the commands mentioned here are to be found in the [APPLICATION.MD](APPLICATION.MD) file. ## Physical interaction @@ -20,7 +20,7 @@ PIN, PUK and pairing password can be changed at any time by the user, after auth ## Application selection -When the client detects a SmartCard, it should try to select the Status Wallet application by sending a selection command. +When the client detects a SmartCard, it should try to select the Status Keycard application by sending a selection command. The applet will respond providing details useful for the next steps. ## PIN sessions diff --git a/build.gradle b/build.gradle index 4cc12b1..66eea94 100644 --- a/build.gradle +++ b/build.gradle @@ -18,10 +18,10 @@ javacard { cap { aid = '0x53:0x74:0x61:0x74:0x75:0x73:0x57:0x61:0x6c:0x6c:0x65:0x74' - packageName = 'im.status.wallet' + packageName = 'im.status.keycard' applet { aid = '0x53:0x74:0x61:0x74:0x75:0x73:0x57:0x61:0x6c:0x6c:0x65:0x74:0x41:0x70:0x70' - className = 'WalletApplet' + className = 'KeycardApplet' } applet { aid = '0x53:0x74:0x61:0x74:0x75:0x73:0x57:0x61:0x6c:0x6c:0x65:0x74:0x4e:0x46:0x43' @@ -42,7 +42,7 @@ dependencies { testCompile('org.web3j:core:2.3.1') testCompile('org.bitcoinj:bitcoinj-core:0.14.5') testCompile("org.bouncycastle:bcprov-jdk15on:1.58") - testCompile("com.github.status-im:hardwallet-lite-sdk:482e32c") + testCompile("com.github.status-im:status-keycard-desktop:42086f6") testCompile("org.junit.jupiter:junit-jupiter-api:5.1.1") testRuntime("org.junit.jupiter:junit-jupiter-engine:5.1.1") } @@ -69,7 +69,7 @@ task install(type: Exec) { open_sc -security 1 -keyind 0 -keyver ${project.properties['im.status.gradle.gpshell.kvn']} -mac_key ${project.properties['im.status.gradle.gpshell.mac_key']} -enc_key ${project.properties['im.status.gradle.gpshell.enc_key']} -kek_key ${project.properties['im.status.gradle.gpshell.kek_key']} send_apdu_nostop -sc 1 -APDU 80E400800E4F0C53746174757357616C6C6574 install_for_load -pkgAID 53746174757357616C6C6574 - load -file build/javacard/im/status/wallet/javacard/wallet.cap + load -file build/javacard/im/status/keycard/javacard/keycard.cap install_for_install -AID 53746174757357616C6C6574417070 -pkgAID 53746174757357616C6C6574 -instAID 53746174757357616C6C6574417070 install_for_install -AID 53746174757357616C6C65744e4643 -pkgAID 53746174757357616C6C6574 -instAID D2760000850101 card_disconnect @@ -80,7 +80,7 @@ task install(type: Exec) { standardInput new ByteArrayInputStream(gpShellScript.getBytes("UTF-8")) } -if (project.properties['im.status.wallet.test.simulated'] != 'true') { +if (project.properties['im.status.keycard.test.simulated'] != 'true') { tasks.install.dependsOn(convertJavacard) tasks.test.dependsOn(install) } @@ -96,8 +96,8 @@ compileTestJava { } afterEvaluate { - if (project.properties['im.status.wallet.test.simulated'] == 'true') { + if (project.properties['im.status.keycard.test.simulated'] == 'true') { def junitPlatformTestTask = tasks.getByName('junitPlatformTest') - junitPlatformTestTask.jvmArgs(['-noverify', '-Dim.status.wallet.test.simulated=true']) + junitPlatformTestTask.jvmArgs(['-noverify', '-Dim.status.keycard.test.simulated=true']) } } diff --git a/src/main/java/im/status/wallet/Crypto.java b/src/main/java/im/status/keycard/Crypto.java similarity index 99% rename from src/main/java/im/status/wallet/Crypto.java rename to src/main/java/im/status/keycard/Crypto.java index e36d113..8cc99fa 100644 --- a/src/main/java/im/status/wallet/Crypto.java +++ b/src/main/java/im/status/keycard/Crypto.java @@ -1,4 +1,4 @@ -package im.status.wallet; +package im.status.keycard; import javacard.framework.JCSystem; import javacard.framework.Util; diff --git a/src/main/java/im/status/wallet/WalletApplet.java b/src/main/java/im/status/keycard/KeycardApplet.java similarity index 99% rename from src/main/java/im/status/wallet/WalletApplet.java rename to src/main/java/im/status/keycard/KeycardApplet.java index 9d15ace..1d7151e 100644 --- a/src/main/java/im/status/wallet/WalletApplet.java +++ b/src/main/java/im/status/keycard/KeycardApplet.java @@ -1,4 +1,4 @@ -package im.status.wallet; +package im.status.keycard; import javacard.framework.*; import javacard.security.*; @@ -7,7 +7,7 @@ import javacardx.crypto.Cipher; /** * The applet's main class. All incoming commands a processed by this class. */ -public class WalletApplet extends Applet { +public class KeycardApplet extends Applet { static final short APPLICATION_VERSION = (short) 0x0200; static final byte INS_GET_STATUS = (byte) 0xF2; @@ -132,7 +132,7 @@ public class WalletApplet extends Applet { * @param bLength length of the installation parameters */ public static void install(byte[] bArray, short bOffset, byte bLength) { - new WalletApplet(bArray, bOffset, bLength); + new KeycardApplet(bArray, bOffset, bLength); } /** @@ -146,7 +146,7 @@ public class WalletApplet extends Applet { * @param bOffset offset where the installation parameters begin * @param bLength length of the installation parameters */ - public WalletApplet(byte[] bArray, short bOffset, byte bLength) { + public KeycardApplet(byte[] bArray, short bOffset, byte bLength) { crypto = new Crypto(); secp256k1 = new SECP256k1(crypto); diff --git a/src/main/java/im/status/wallet/NDEFApplet.java b/src/main/java/im/status/keycard/NDEFApplet.java similarity index 99% rename from src/main/java/im/status/wallet/NDEFApplet.java rename to src/main/java/im/status/keycard/NDEFApplet.java index e6a05ae..80f21b0 100644 --- a/src/main/java/im/status/wallet/NDEFApplet.java +++ b/src/main/java/im/status/keycard/NDEFApplet.java @@ -1,4 +1,4 @@ -package im.status.wallet; +package im.status.keycard; import javacard.framework.*; diff --git a/src/main/java/im/status/wallet/SECP256k1.java b/src/main/java/im/status/keycard/SECP256k1.java similarity index 99% rename from src/main/java/im/status/wallet/SECP256k1.java rename to src/main/java/im/status/keycard/SECP256k1.java index d6dbb1e..1a9bbc2 100644 --- a/src/main/java/im/status/wallet/SECP256k1.java +++ b/src/main/java/im/status/keycard/SECP256k1.java @@ -1,4 +1,4 @@ -package im.status.wallet; +package im.status.keycard; import javacard.security.ECKey; import javacard.security.ECPrivateKey; diff --git a/src/main/java/im/status/wallet/SecureChannel.java b/src/main/java/im/status/keycard/SecureChannel.java similarity index 99% rename from src/main/java/im/status/wallet/SecureChannel.java rename to src/main/java/im/status/keycard/SecureChannel.java index 6a701b9..b278ce3 100644 --- a/src/main/java/im/status/wallet/SecureChannel.java +++ b/src/main/java/im/status/keycard/SecureChannel.java @@ -1,4 +1,4 @@ -package im.status.wallet; +package im.status.keycard; import javacard.framework.*; import javacard.security.*; diff --git a/src/main/java/im/status/wallet/SharedMemory.java b/src/main/java/im/status/keycard/SharedMemory.java similarity index 90% rename from src/main/java/im/status/wallet/SharedMemory.java rename to src/main/java/im/status/keycard/SharedMemory.java index 0e77ed0..33fd00b 100644 --- a/src/main/java/im/status/wallet/SharedMemory.java +++ b/src/main/java/im/status/keycard/SharedMemory.java @@ -1,4 +1,4 @@ -package im.status.wallet; +package im.status.keycard; /** * Keep references to data structures shared across applet instances of this package. diff --git a/src/test/java/im/status/wallet/WalletAppletTest.java b/src/test/java/im/status/keycard/KeycardTest.java similarity index 89% rename from src/test/java/im/status/wallet/WalletAppletTest.java rename to src/test/java/im/status/keycard/KeycardTest.java index 3c3bae6..ebe7c33 100644 --- a/src/test/java/im/status/wallet/WalletAppletTest.java +++ b/src/test/java/im/status/keycard/KeycardTest.java @@ -1,9 +1,8 @@ -package im.status.wallet; +package im.status.keycard; import com.licel.jcardsim.smartcardio.CardSimulator; import com.licel.jcardsim.smartcardio.CardTerminalSimulator; import com.licel.jcardsim.utils.AIDUtil; -import im.status.hardwallet.lite.WalletAppletCommandSet; import javacard.framework.AID; import org.bitcoinj.core.ECKey; import org.bitcoinj.crypto.ChildNumber; @@ -42,21 +41,21 @@ import java.util.Random; import static org.apache.commons.codec.digest.DigestUtils.sha256; import static org.junit.jupiter.api.Assertions.*; -@DisplayName("Test the Wallet Applet") -public class WalletAppletTest { - // Psiring key is WalletAppletTest - public static final byte[] SHARED_SECRET = new byte[] { (byte) 0xe9, (byte) 0x29, (byte) 0xd4, (byte) 0x25, (byte) 0xd7, (byte) 0xf7, (byte) 0x3c, (byte) 0x2a, (byte) 0x0a, (byte) 0x24, (byte) 0xff, (byte) 0xef, (byte) 0xad, (byte) 0x87, (byte) 0xb6, (byte) 0x5e, (byte) 0x9b, (byte) 0x2e, (byte) 0xe9, (byte) 0x66, (byte) 0x03, (byte) 0xea, (byte) 0xb3, (byte) 0x4d, (byte) 0x64, (byte) 0x08, (byte) 0x8b, (byte) 0x5a, (byte) 0xae, (byte) 0x2a, (byte) 0x02, (byte) 0x6f }; +@DisplayName("Test the Keycard Applet") +public class KeycardTest { + // Psiring key is KeycardTest + public static final byte[] SHARED_SECRET = Hex.decode("2194524CF8A99C34B9F6C6894D07245AA2D5CFE6327C27D5ACDCC95DA203ED28"); private static CardTerminal cardTerminal; private static CardChannel apduChannel; private static CardSimulator simulator; private TestSecureChannelSession secureChannel; - private TestWalletAppletCommandSet cmdSet; + private TestKeycardCommandSet cmdSet; private static final boolean USE_SIMULATOR; static { - USE_SIMULATOR = !System.getProperty("im.status.wallet.test.simulated", "false").equals("false"); + USE_SIMULATOR = !System.getProperty("im.status.keycard.test.simulated", "false").equals("false"); } @BeforeAll @@ -65,8 +64,8 @@ public class WalletAppletTest { if (USE_SIMULATOR) { simulator = new CardSimulator(); - AID appletAID = AIDUtil.create(WalletAppletCommandSet.APPLET_AID); - simulator.installApplet(appletAID, WalletApplet.class); + AID appletAID = AIDUtil.create(KeycardCommandSet.APPLET_AID); + simulator.installApplet(appletAID, KeycardApplet.class); cardTerminal = CardTerminalSimulator.terminal(simulator); } else { TerminalFactory tf = TerminalFactory.getDefault(); @@ -86,19 +85,19 @@ public class WalletAppletTest { } private static void initIfNeeded() throws CardException { - WalletAppletCommandSet cmdSet = new WalletAppletCommandSet(apduChannel); + KeycardCommandSet cmdSet = new KeycardCommandSet(apduChannel); byte[] data = cmdSet.select().getData(); - if (data[0] == WalletApplet.TLV_APPLICATION_INFO_TEMPLATE) return; + if (data[0] == KeycardApplet.TLV_APPLICATION_INFO_TEMPLATE) return; assertEquals(0x9000, cmdSet.init("000000", "123456789012", SHARED_SECRET).getSW()); } @BeforeEach void init() throws CardException { reset(); - cmdSet = new TestWalletAppletCommandSet(apduChannel); + cmdSet = new TestKeycardCommandSet(apduChannel); secureChannel = new TestSecureChannelSession(); cmdSet.setSecureChannel(secureChannel); - WalletAppletCommandSet.checkOK(cmdSet.select()); + KeycardCommandSet.checkOK(cmdSet.select()); cmdSet.setSecureChannel(secureChannel); cmdSet.autoPair(SHARED_SECRET); } @@ -121,14 +120,14 @@ public class WalletAppletTest { ResponseAPDU response = cmdSet.select(); assertEquals(0x9000, response.getSW()); byte[] data = response.getData(); - assertEquals(WalletApplet.TLV_APPLICATION_INFO_TEMPLATE, data[0]); - assertEquals(WalletApplet.TLV_UID, data[2]); - assertEquals(WalletApplet.TLV_PUB_KEY, data[20]); - assertEquals(WalletApplet.TLV_INT, data[22 + data[21]]); - assertEquals(WalletApplet.APPLICATION_VERSION >> 8, data[24 + data[21]]); - assertEquals(WalletApplet.APPLICATION_VERSION & 0xFF, data[25 + data[21]]); - assertEquals(WalletApplet.TLV_INT, data[26 + data[21]]); - assertEquals(WalletApplet.TLV_KEY_UID, data[29 + data[21]]); + assertEquals(KeycardApplet.TLV_APPLICATION_INFO_TEMPLATE, data[0]); + assertEquals(KeycardApplet.TLV_UID, data[2]); + assertEquals(KeycardApplet.TLV_PUB_KEY, data[20]); + assertEquals(KeycardApplet.TLV_INT, data[22 + data[21]]); + assertEquals(KeycardApplet.APPLICATION_VERSION >> 8, data[24 + data[21]]); + assertEquals(KeycardApplet.APPLICATION_VERSION & 0xFF, data[25 + data[21]]); + assertEquals(KeycardApplet.TLV_INT, data[26 + data[21]]); + assertEquals(KeycardApplet.TLV_KEY_UID, data[29 + data[21]]); } @Test @@ -150,7 +149,7 @@ public class WalletAppletTest { // Send command before MUTUALLY AUTHENTICATE secureChannel.reset(); - response = cmdSet.getStatus(WalletApplet.GET_STATUS_P1_APPLICATION); + response = cmdSet.getStatus(KeycardApplet.GET_STATUS_P1_APPLICATION); assertEquals(0x6985, response.getSW()); // Perform mutual authentication @@ -160,7 +159,7 @@ public class WalletAppletTest { assertTrue(secureChannel.verifyMutuallyAuthenticateResponse(response)); // Verify that the channel is open - response = cmdSet.getStatus(WalletApplet.GET_STATUS_P1_APPLICATION); + response = cmdSet.getStatus(KeycardApplet.GET_STATUS_P1_APPLICATION); assertEquals(0x9000, response.getSW()); // Verify that the keys are changed correctly. Since we do not know the internal counter we just iterate until that @@ -211,13 +210,13 @@ public class WalletAppletTest { cmdSet.autoOpenSecureChannel(); // MUTUALLY AUTHENTICATE has no effect on an already open secure channel - response = cmdSet.getStatus(WalletApplet.GET_STATUS_P1_APPLICATION); + response = cmdSet.getStatus(KeycardApplet.GET_STATUS_P1_APPLICATION); assertEquals(0x9000, response.getSW()); response = cmdSet.mutuallyAuthenticate(); assertEquals(0x6985, response.getSW()); - response = cmdSet.getStatus(WalletApplet.GET_STATUS_P1_APPLICATION); + response = cmdSet.getStatus(KeycardApplet.GET_STATUS_P1_APPLICATION); assertEquals(0x9000, response.getSW()); } @@ -318,33 +317,33 @@ public class WalletAppletTest { @DisplayName("GET STATUS command") void getStatusTest() throws CardException { // Security condition violation: SecureChannel not open - ResponseAPDU response = cmdSet.getStatus(WalletApplet.GET_STATUS_P1_APPLICATION); + ResponseAPDU response = cmdSet.getStatus(KeycardApplet.GET_STATUS_P1_APPLICATION); assertEquals(0x6985, response.getSW()); cmdSet.autoOpenSecureChannel(); // Good case. Since the order of test execution is undefined, the test cannot know if the keys are initialized or not. // Additionally, support for public key derivation is hw dependent. - response = cmdSet.getStatus(WalletApplet.GET_STATUS_P1_APPLICATION); + response = cmdSet.getStatus(KeycardApplet.GET_STATUS_P1_APPLICATION); assertEquals(0x9000, response.getSW()); byte[] data = response.getData(); assertTrue(Hex.toHexString(data).matches("a30c0201030201050101[0f][0f]")); response = cmdSet.verifyPIN("123456"); assertEquals(0x63C2, response.getSW()); - response = cmdSet.getStatus(WalletApplet.GET_STATUS_P1_APPLICATION); + response = cmdSet.getStatus(KeycardApplet.GET_STATUS_P1_APPLICATION); assertEquals(0x9000, response.getSW()); data = response.getData(); assertTrue(Hex.toHexString(data).matches("a30c0201020201050101[0f][0f]")); response = cmdSet.verifyPIN("000000"); assertEquals(0x9000, response.getSW()); - response = cmdSet.getStatus(WalletApplet.GET_STATUS_P1_APPLICATION); + response = cmdSet.getStatus(KeycardApplet.GET_STATUS_P1_APPLICATION); assertEquals(0x9000, response.getSW()); data = response.getData(); assertTrue(Hex.toHexString(data).matches("a30c0201030201050101[0f][0f]")); // Check that key path is empty - response = cmdSet.getStatus(WalletApplet.GET_STATUS_P1_KEY_PATH); + response = cmdSet.getStatus(KeycardApplet.GET_STATUS_P1_KEY_PATH); assertEquals(0x9000, response.getSW()); data = response.getData(); assertEquals(0, data.length); @@ -423,13 +422,13 @@ public class WalletAppletTest { @DisplayName("CHANGE PIN command") void changePinTest() throws CardException { // Security condition violation: SecureChannel not open - ResponseAPDU response = cmdSet.changePIN(WalletApplet.CHANGE_PIN_P1_USER_PIN, "123456"); + ResponseAPDU response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_USER_PIN, "123456"); assertEquals(0x6985, response.getSW()); cmdSet.autoOpenSecureChannel(); // Security condition violation: PIN n ot verified - response = cmdSet.changePIN(WalletApplet.CHANGE_PIN_P1_USER_PIN, "123456"); + response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_USER_PIN, "123456"); assertEquals(0x6985, response.getSW()); response = cmdSet.verifyPIN("000000"); @@ -440,37 +439,37 @@ public class WalletAppletTest { assertEquals(0x6a86, response.getSW()); // Test wrong PIN formats (non-digits, too short, too long) - response = cmdSet.changePIN(WalletApplet.CHANGE_PIN_P1_USER_PIN, "654a21"); + response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_USER_PIN, "654a21"); assertEquals(0x6A80, response.getSW()); - response = cmdSet.changePIN(WalletApplet.CHANGE_PIN_P1_USER_PIN, "54321"); + response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_USER_PIN, "54321"); assertEquals(0x6A80, response.getSW()); - response = cmdSet.changePIN(WalletApplet.CHANGE_PIN_P1_USER_PIN, "7654321"); + response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_USER_PIN, "7654321"); assertEquals(0x6A80, response.getSW()); // Test wrong PUK formats - response = cmdSet.changePIN(WalletApplet.CHANGE_PIN_P1_PUK, "210987654a21"); + response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_PUK, "210987654a21"); assertEquals(0x6A80, response.getSW()); - response = cmdSet.changePIN(WalletApplet.CHANGE_PIN_P1_PUK, "10987654321"); + response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_PUK, "10987654321"); assertEquals(0x6A80, response.getSW()); - response = cmdSet.changePIN(WalletApplet.CHANGE_PIN_P1_PUK, "3210987654321"); + response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_PUK, "3210987654321"); assertEquals(0x6A80, response.getSW()); // Test wrong pairing secret format (too long, too short) - response = cmdSet.changePIN(WalletApplet.CHANGE_PIN_P1_PAIRING_SECRET, "abcdefghilmnopqrstuvz123456789012"); + response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_PAIRING_SECRET, "abcdefghilmnopqrstuvz123456789012"); assertEquals(0x6A80, response.getSW()); - response = cmdSet.changePIN(WalletApplet.CHANGE_PIN_P1_PAIRING_SECRET, "abcdefghilmnopqrstuvz1234567890"); + response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_PAIRING_SECRET, "abcdefghilmnopqrstuvz1234567890"); assertEquals(0x6A80, response.getSW()); // Change PIN correctly, check that after PIN change the PIN remains validated - response = cmdSet.changePIN(WalletApplet.CHANGE_PIN_P1_USER_PIN, "123456"); + response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_USER_PIN, "123456"); assertEquals(0x9000, response.getSW()); - response = cmdSet.changePIN(WalletApplet.CHANGE_PIN_P1_USER_PIN, "654321"); + response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_USER_PIN, "654321"); assertEquals(0x9000, response.getSW()); // Reset card and verify that the new PIN has really been set @@ -480,7 +479,7 @@ public class WalletAppletTest { assertEquals(0x9000, response.getSW()); // Change PUK - response = cmdSet.changePIN(WalletApplet.CHANGE_PIN_P1_PUK, "210987654321"); + response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_PUK, "210987654321"); assertEquals(0x9000, response.getSW()); resetAndSelectAndOpenSC(); @@ -500,11 +499,11 @@ public class WalletAppletTest { assertEquals(0x9000, response.getSW()); // Reset PUK - response = cmdSet.changePIN(WalletApplet.CHANGE_PIN_P1_PUK, "123456789012"); + response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_PUK, "123456789012"); assertEquals(0x9000, response.getSW()); // Change the pairing secret - response = cmdSet.changePIN(WalletApplet.CHANGE_PIN_P1_PAIRING_SECRET, "abcdefghilmnopqrstuvz12345678901"); + response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_PAIRING_SECRET, "abcdefghilmnopqrstuvz12345678901"); assertEquals(0x9000, response.getSW()); cmdSet.autoUnpair(); reset(); @@ -518,7 +517,7 @@ public class WalletAppletTest { response = cmdSet.verifyPIN("000000"); assertEquals(0x9000, response.getSW()); - response = cmdSet.changePIN(WalletApplet.CHANGE_PIN_P1_PAIRING_SECRET, SHARED_SECRET); + response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_PAIRING_SECRET, SHARED_SECRET); assertEquals(0x9000, response.getSW()); } @@ -567,7 +566,7 @@ public class WalletAppletTest { assertEquals(0x9000, response.getSW()); // Reset the PIN to make further tests possible - response = cmdSet.changePIN(WalletApplet.CHANGE_PIN_P1_USER_PIN, "000000"); + response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_USER_PIN, "000000"); assertEquals(0x9000, response.getSW()); } @@ -595,14 +594,14 @@ public class WalletAppletTest { assertEquals(0x6A86, response.getSW()); // Wrong data (wrong template, missing private key, invalid keys) - response = cmdSet.loadKey(new byte[]{(byte) 0xAA, 0x02, (byte) 0x80, 0x00}, WalletApplet.LOAD_KEY_P1_EC); + response = cmdSet.loadKey(new byte[]{(byte) 0xAA, 0x02, (byte) 0x80, 0x00}, KeycardApplet.LOAD_KEY_P1_EC); assertEquals(0x6A80, response.getSW()); - response = cmdSet.loadKey(new byte[]{(byte) 0xA1, 0x02, (byte) 0x80, 0x00}, WalletApplet.LOAD_KEY_P1_EC); + response = cmdSet.loadKey(new byte[]{(byte) 0xA1, 0x02, (byte) 0x80, 0x00}, KeycardApplet.LOAD_KEY_P1_EC); assertEquals(0x6A80, response.getSW()); if (!USE_SIMULATOR) { // the simulator does not check the key format - response = cmdSet.loadKey(new byte[]{(byte) 0xA1, 0x06, (byte) 0x80, 0x01, 0x01, (byte) 0x81, 0x01, 0x02}, WalletApplet.LOAD_KEY_P1_EC); + response = cmdSet.loadKey(new byte[]{(byte) 0xA1, 0x06, (byte) 0x80, 0x01, 0x01, (byte) 0x81, 0x01, 0x02}, KeycardApplet.LOAD_KEY_P1_EC); assertEquals(0x6A80, response.getSW()); } @@ -791,7 +790,7 @@ public class WalletAppletTest { verifyKeyDerivation(keyPair, chainCode, new int[]{1, 0x80000000, 2}); // From parent - response = cmdSet.deriveKey(new byte[]{0x00, 0x00, 0x00, 0x03}, WalletApplet.DERIVE_P1_SOURCE_PARENT); + response = cmdSet.deriveKey(new byte[]{0x00, 0x00, 0x00, 0x03}, KeycardApplet.DERIVE_P1_SOURCE_PARENT); assertEquals(0x9000, response.getSW()); verifyKeyDerivation(keyPair, chainCode, new int[]{1, 0x80000000, 3}); @@ -801,15 +800,15 @@ public class WalletAppletTest { verifyKeyDerivation(keyPair, chainCode, new int[0]); // Try parent when none available - response = cmdSet.deriveKey(new byte[]{0x00, 0x00, 0x00, 0x03}, WalletApplet.DERIVE_P1_SOURCE_PARENT); + response = cmdSet.deriveKey(new byte[]{0x00, 0x00, 0x00, 0x03}, KeycardApplet.DERIVE_P1_SOURCE_PARENT); assertEquals(0x6B00, response.getSW()); // 3 levels with hardened key using separate commands - response = cmdSet.deriveKey(new byte[]{0x00, 0x00, 0x00, 0x01}, WalletApplet.DERIVE_P1_SOURCE_MASTER); + response = cmdSet.deriveKey(new byte[]{0x00, 0x00, 0x00, 0x01}, KeycardApplet.DERIVE_P1_SOURCE_MASTER); assertEquals(0x9000, response.getSW()); - response = cmdSet.deriveKey(new byte[]{(byte) 0x80, 0x00, 0x00, 0x00}, WalletApplet.DERIVE_P1_SOURCE_CURRENT); + response = cmdSet.deriveKey(new byte[]{(byte) 0x80, 0x00, 0x00, 0x00}, KeycardApplet.DERIVE_P1_SOURCE_CURRENT); assertEquals(0x9000, response.getSW()); - response = cmdSet.deriveKey(new byte[]{0x00, 0x00, 0x00, 0x02}, WalletApplet.DERIVE_P1_SOURCE_CURRENT); + response = cmdSet.deriveKey(new byte[]{0x00, 0x00, 0x00, 0x02}, KeycardApplet.DERIVE_P1_SOURCE_CURRENT); assertEquals(0x9000, response.getSW()); verifyKeyDerivation(keyPair, chainCode, new int[]{1, 0x80000000, 2}); @@ -890,7 +889,7 @@ public class WalletAppletTest { // Wrong data response = cmdSet.setPinlessPath(new byte[] {0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}); assertEquals(0x6a80, response.getSW()); - response = cmdSet.setPinlessPath(new byte[(WalletApplet.KEY_PATH_MAX_DEPTH + 1)* 4]); + response = cmdSet.setPinlessPath(new byte[(KeycardApplet.KEY_PATH_MAX_DEPTH + 1)* 4]); assertEquals(0x6a80, response.getSW()); // Correct @@ -901,11 +900,11 @@ public class WalletAppletTest { resetAndSelectAndOpenSC(); response = cmdSet.sign(hash); assertEquals(0x6985, response.getSW()); - response = cmdSet.deriveKey(new byte[] {0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01}, WalletApplet.DERIVE_P1_SOURCE_MASTER); + response = cmdSet.deriveKey(new byte[] {0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01}, KeycardApplet.DERIVE_P1_SOURCE_MASTER); assertEquals(0x9000, response.getSW()); response = cmdSet.sign(hash); assertEquals(0x6985, response.getSW()); - response = cmdSet.deriveKey(new byte[] {0x00, 0x00, 0x00, 0x02}, WalletApplet.DERIVE_P1_SOURCE_CURRENT); + response = cmdSet.deriveKey(new byte[] {0x00, 0x00, 0x00, 0x02}, KeycardApplet.DERIVE_P1_SOURCE_CURRENT); assertEquals(0x9000, response.getSW()); response = cmdSet.sign(hash); assertEquals(0x9000, response.getSW()); @@ -919,7 +918,7 @@ public class WalletAppletTest { response = cmdSet.sign(hash); assertEquals(0x6985, response.getSW()); assertEquals(0x6985, response.getSW()); - response = cmdSet.deriveKey(new byte[] {0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01}, WalletApplet.DERIVE_P1_SOURCE_MASTER); + response = cmdSet.deriveKey(new byte[] {0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01}, KeycardApplet.DERIVE_P1_SOURCE_MASTER); assertEquals(0x9000, response.getSW()); response = cmdSet.sign(hash); assertEquals(0x9000, response.getSW()); @@ -932,7 +931,7 @@ public class WalletAppletTest { resetAndSelectAndOpenSC(); response = cmdSet.sign(hash); assertEquals(0x6985, response.getSW()); - response = cmdSet.deriveKey(new byte[] {0x00, 0x00, 0x00, 0x02}, WalletApplet.DERIVE_P1_SOURCE_MASTER); + response = cmdSet.deriveKey(new byte[] {0x00, 0x00, 0x00, 0x02}, KeycardApplet.DERIVE_P1_SOURCE_MASTER); assertEquals(0x6985, response.getSW()); } @@ -963,12 +962,12 @@ public class WalletAppletTest { response = cmdSet.exportCurrentKey(false); assertEquals(0x6985, response.getSW()); - response = cmdSet.deriveKey(new byte[] {(byte) 0x80, 0x00, 0x00, 0x2B, (byte) 0x80, 0x00, 0x00, 0x3C, (byte) 0x80, 0x00, 0x06, 0x2c, (byte) 0x00, 0x00, 0x00, 0x00, (byte) 0x00, 0x00, 0x00, 0x00}, WalletApplet.DERIVE_P1_SOURCE_MASTER); + response = cmdSet.deriveKey(new byte[] {(byte) 0x80, 0x00, 0x00, 0x2B, (byte) 0x80, 0x00, 0x00, 0x3C, (byte) 0x80, 0x00, 0x06, 0x2c, (byte) 0x00, 0x00, 0x00, 0x00, (byte) 0x00, 0x00, 0x00, 0x00}, KeycardApplet.DERIVE_P1_SOURCE_MASTER); assertEquals(0x9000, response.getSW()); response = cmdSet.exportCurrentKey(false); assertEquals(0x6985, response.getSW()); - response = cmdSet.deriveKey(new byte[] {(byte) 0x80, 0x00, 0x00, 0x2B, (byte) 0x80, 0x00, 0x00, 0x3C, (byte) 0x80, 0x00, 0x06, 0x2D, (byte) 0x00, 0x00, 0x00, 0x00}, WalletApplet.DERIVE_P1_SOURCE_MASTER); + response = cmdSet.deriveKey(new byte[] {(byte) 0x80, 0x00, 0x00, 0x2B, (byte) 0x80, 0x00, 0x00, 0x3C, (byte) 0x80, 0x00, 0x06, 0x2D, (byte) 0x00, 0x00, 0x00, 0x00}, KeycardApplet.DERIVE_P1_SOURCE_MASTER); assertEquals(0x9000, response.getSW()); response = cmdSet.exportCurrentKey(false); assertEquals(0x6985, response.getSW()); @@ -981,17 +980,17 @@ public class WalletAppletTest { verifyExportedKey(keyTemplate, keyPair, chainCode, new int[] { 0x8000002b, 0x8000003c, 0x8000062d, 0x00000000 }, true, false); // Derive & Make current - response = cmdSet.exportKey(new byte[] {(byte) 0x80, 0x00, 0x00, 0x2B, (byte) 0x80, 0x00, 0x00, 0x3C, (byte) 0x80, 0x00, 0x06, 0x2D, (byte) 0x00, 0x00, 0x00, 0x00, (byte) 0x00, 0x00, 0x00, 0x00}, WalletApplet.DERIVE_P1_SOURCE_MASTER,true,false); + response = cmdSet.exportKey(new byte[] {(byte) 0x80, 0x00, 0x00, 0x2B, (byte) 0x80, 0x00, 0x00, 0x3C, (byte) 0x80, 0x00, 0x06, 0x2D, (byte) 0x00, 0x00, 0x00, 0x00, (byte) 0x00, 0x00, 0x00, 0x00}, KeycardApplet.DERIVE_P1_SOURCE_MASTER,true,false); assertEquals(0x9000, response.getSW()); keyTemplate = response.getData(); verifyExportedKey(keyTemplate, keyPair, chainCode, new int[] { 0x8000002b, 0x8000003c, 0x8000062d, 0x00000000, 0x00000000 }, false, false); // Derive without making current - response = cmdSet.exportKey(new byte[] {(byte) 0x00, 0x00, 0x00, 0x01}, WalletApplet.DERIVE_P1_SOURCE_PARENT, false,false); + response = cmdSet.exportKey(new byte[] {(byte) 0x00, 0x00, 0x00, 0x01}, KeycardApplet.DERIVE_P1_SOURCE_PARENT, false,false); assertEquals(0x9000, response.getSW()); keyTemplate = response.getData(); verifyExportedKey(keyTemplate, keyPair, chainCode, new int[] { 0x8000002b, 0x8000003c, 0x8000062d, 0x00000000, 0x00000001 }, false, true); - response = cmdSet.getStatus(WalletApplet.GET_STATUS_P1_KEY_PATH); + response = cmdSet.getStatus(KeycardApplet.GET_STATUS_P1_KEY_PATH); assertEquals(0x9000, response.getSW()); assertArrayEquals(new byte[] {(byte) 0x80, 0x00, 0x00, 0x2B, (byte) 0x80, 0x00, 0x00, 0x3C, (byte) 0x80, 0x00, 0x06, 0x2D, (byte) 0x00, 0x00, 0x00, 0x00, (byte) 0x00, 0x00, 0x00, 0x00}, response.getData()); @@ -1002,7 +1001,7 @@ public class WalletAppletTest { verifyExportedKey(keyTemplate, keyPair, chainCode, new int[] { 0x8000002b, 0x8000003c, 0x8000062d, 0x00000000, 0x00000000 }, false, false); // Reset - response = cmdSet.deriveKey(new byte[0], WalletApplet.DERIVE_P1_SOURCE_MASTER); + response = cmdSet.deriveKey(new byte[0], KeycardApplet.DERIVE_P1_SOURCE_MASTER); assertEquals(0x9000, response.getSW()); } @@ -1175,7 +1174,7 @@ public class WalletAppletTest { for (int i = 0; i < SAMPLE_COUNT; i++) { time = System.currentTimeMillis(); - response = cmdSet.deriveKey(new byte[] { (byte) 0x80, 0x00, 0x00, 0x2C, (byte) 0x80, 0x00, 0x00, 0x3C, (byte) 0x80, 0x00, 0x00, 0x00, (byte) 0x00, 0x00, 0x00, 0x00, (byte) 0x00, 0x00, 0x00, 0x00}, WalletApplet.DERIVE_P1_SOURCE_MASTER); + response = cmdSet.deriveKey(new byte[] { (byte) 0x80, 0x00, 0x00, 0x2C, (byte) 0x80, 0x00, 0x00, 0x3C, (byte) 0x80, 0x00, 0x00, 0x00, (byte) 0x00, 0x00, 0x00, 0x00, (byte) 0x00, 0x00, 0x00, 0x00}, KeycardApplet.DERIVE_P1_SOURCE_MASTER); deriveAccount += System.currentTimeMillis() - time; assertEquals(0x9000, response.getSW()); } @@ -1184,7 +1183,7 @@ public class WalletAppletTest { for (int i = 0; i < SAMPLE_COUNT; i++) { time = System.currentTimeMillis(); - response = cmdSet.deriveKey(new byte[] {0x00, 0x00, 0x00, (byte) i}, WalletApplet.DERIVE_P1_SOURCE_PARENT); + response = cmdSet.deriveKey(new byte[] {0x00, 0x00, 0x00, (byte) i}, KeycardApplet.DERIVE_P1_SOURCE_PARENT); deriveParent += System.currentTimeMillis() - time; assertEquals(0x9000, response.getSW()); } @@ -1193,7 +1192,7 @@ public class WalletAppletTest { for (int i = 0; i < SAMPLE_COUNT; i++) { time = System.currentTimeMillis(); - response = cmdSet.deriveKey(new byte[] {(byte) 0x80, 0x00, 0x00, (byte) i}, WalletApplet.DERIVE_P1_SOURCE_PARENT); + response = cmdSet.deriveKey(new byte[] {(byte) 0x80, 0x00, 0x00, (byte) i}, KeycardApplet.DERIVE_P1_SOURCE_PARENT); deriveParentHardened += System.currentTimeMillis() - time; assertEquals(0x9000, response.getSW()); } @@ -1219,17 +1218,17 @@ public class WalletAppletTest { } private byte[] extractPublicKeyFromSignature(byte[] sig) { - assertEquals(WalletApplet.TLV_SIGNATURE_TEMPLATE, sig[0]); + assertEquals(KeycardApplet.TLV_SIGNATURE_TEMPLATE, sig[0]); assertEquals((byte) 0x81, sig[1]); - assertEquals(WalletApplet.TLV_PUB_KEY, sig[3]); + assertEquals(KeycardApplet.TLV_PUB_KEY, sig[3]); return Arrays.copyOfRange(sig, 5, 5 + sig[4]); } private byte[] extractPublicKeyFromSelect(byte[] select) { - assertEquals(WalletApplet.TLV_APPLICATION_INFO_TEMPLATE, select[0]); - assertEquals(WalletApplet.TLV_UID, select[2]); - assertEquals(WalletApplet.TLV_PUB_KEY, select[20]); + assertEquals(KeycardApplet.TLV_APPLICATION_INFO_TEMPLATE, select[0]); + assertEquals(KeycardApplet.TLV_UID, select[2]); + assertEquals(KeycardApplet.TLV_PUB_KEY, select[20]); return Arrays.copyOfRange(select, 22, 22 + select[21]); } @@ -1291,7 +1290,7 @@ public class WalletAppletTest { assertTrue(key.verify(hash, sig)); assertArrayEquals(key.getPubKeyPoint().getEncoded(false), publicKey); - resp = cmdSet.getStatus(WalletApplet.GET_STATUS_P1_KEY_PATH); + resp = cmdSet.getStatus(KeycardApplet.GET_STATUS_P1_KEY_PATH); assertEquals(0x9000, resp.getSW()); byte[] rawPath = resp.getData(); @@ -1306,11 +1305,11 @@ public class WalletAppletTest { private void verifyExportedKey(byte[] keyTemplate, KeyPair keyPair, byte[] chainCode, int[] path, boolean publicOnly, boolean noPubKey) { ECKey key = deriveKey(keyPair, chainCode, path).decompress(); - assertEquals(WalletApplet.TLV_KEY_TEMPLATE, keyTemplate[0]); + assertEquals(KeycardApplet.TLV_KEY_TEMPLATE, keyTemplate[0]); int pubKeyLen = 0; if (!noPubKey) { - assertEquals(WalletApplet.TLV_PUB_KEY, keyTemplate[2]); + assertEquals(KeycardApplet.TLV_PUB_KEY, keyTemplate[2]); byte[] pubKey = Arrays.copyOfRange(keyTemplate, 4, 4 + keyTemplate[3]); assertArrayEquals(key.getPubKey(), pubKey); pubKeyLen = 2 + pubKey.length; @@ -1320,7 +1319,7 @@ public class WalletAppletTest { assertEquals(pubKeyLen, keyTemplate[1]); assertEquals(pubKeyLen + 2, keyTemplate.length); } else { - assertEquals(WalletApplet.TLV_PRIV_KEY, keyTemplate[2 + pubKeyLen]); + assertEquals(KeycardApplet.TLV_PRIV_KEY, keyTemplate[2 + pubKeyLen]); byte[] privateKey = Arrays.copyOfRange(keyTemplate, 4 + pubKeyLen, 4 + pubKeyLen + keyTemplate[3 + pubKeyLen]); byte[] tPrivKey = key.getPrivKey().toByteArray(); diff --git a/src/test/java/im/status/wallet/TestWalletAppletCommandSet.java b/src/test/java/im/status/keycard/TestKeycardCommandSet.java similarity index 85% rename from src/test/java/im/status/wallet/TestWalletAppletCommandSet.java rename to src/test/java/im/status/keycard/TestKeycardCommandSet.java index a9d5d32..ab43052 100644 --- a/src/test/java/im/status/wallet/TestWalletAppletCommandSet.java +++ b/src/test/java/im/status/keycard/TestKeycardCommandSet.java @@ -1,14 +1,13 @@ -package im.status.wallet; +package im.status.keycard; -import im.status.hardwallet.lite.WalletAppletCommandSet; import org.web3j.crypto.ECKeyPair; import javax.smartcardio.CardChannel; import javax.smartcardio.CardException; import javax.smartcardio.ResponseAPDU; -public class TestWalletAppletCommandSet extends WalletAppletCommandSet { - public TestWalletAppletCommandSet(CardChannel apduChannel) { +public class TestKeycardCommandSet extends KeycardCommandSet { + public TestKeycardCommandSet(CardChannel apduChannel) { super(apduChannel); } diff --git a/src/test/java/im/status/wallet/TestSecureChannelSession.java b/src/test/java/im/status/keycard/TestSecureChannelSession.java similarity index 60% rename from src/test/java/im/status/wallet/TestSecureChannelSession.java rename to src/test/java/im/status/keycard/TestSecureChannelSession.java index 4b8473a..b6cf7da 100644 --- a/src/test/java/im/status/wallet/TestSecureChannelSession.java +++ b/src/test/java/im/status/keycard/TestSecureChannelSession.java @@ -1,6 +1,4 @@ -package im.status.wallet; - -import im.status.hardwallet.lite.SecureChannelSession; +package im.status.keycard; public class TestSecureChannelSession extends SecureChannelSession { public void setOpen() {