diff --git a/demo/src/main/java/im/status/hardwallet_lite_android/app/MainActivity.java b/demo/src/main/java/im/status/hardwallet_lite_android/app/MainActivity.java index f1e9c38..226f410 100644 --- a/demo/src/main/java/im/status/hardwallet_lite_android/app/MainActivity.java +++ b/demo/src/main/java/im/status/hardwallet_lite_android/app/MainActivity.java @@ -6,8 +6,8 @@ import android.support.v7.app.AppCompatActivity; import android.util.Log; import im.status.hardwallet_lite_android.demo.R; import im.status.hardwallet_lite_android.io.CardChannel; +import im.status.hardwallet_lite_android.io.CardListener; import im.status.hardwallet_lite_android.io.CardManager; -import im.status.hardwallet_lite_android.io.OnCardConnectedListener; import im.status.hardwallet_lite_android.wallet.*; import org.spongycastle.util.encoders.Hex; @@ -25,7 +25,7 @@ public class MainActivity extends AppCompatActivity { nfcAdapter = NfcAdapter.getDefaultAdapter(this); cardManager = new CardManager(); - cardManager.setOnCardConnectedListener(new OnCardConnectedListener() { + cardManager.setCardListener(new CardListener() { @Override public void onConnected(CardChannel cardChannel) { try { @@ -87,11 +87,16 @@ public class MainActivity extends AppCompatActivity { cmdSet.generateKey(); } - // Key derivation is needed to select the desired key. The derived key remains current until a new derive - // command is sent (it is not lost on power loss). With GET STATUS one can retrieve the current path. - cmdSet.deriveKey("m/44'/0'/0'/0/0").checkOK(); + // Get the current key path using GET STATUS + KeyPath currentPath = new KeyPath(cmdSet.getStatus(WalletAppletCommandSet.GET_STATUS_P1_KEY_PATH).checkOK().getData()); + Log.i(TAG, "Current key path: " + currentPath); - Log.i(TAG, "Derived m/44'/0'/0'/0/0"); + if (!currentPath.toString().equals("m/44'/0'/0'/0/0")) { + // Key derivation is needed to select the desired key. The derived key remains current until a new derive + // command is sent (it is not lost on power loss). + cmdSet.deriveKey("m/44'/0'/0'/0/0").checkOK(); + Log.i(TAG, "Derived m/44'/0'/0'/0/0"); + } byte[] hash = "thiscouldbeahashintheorysoitisok".getBytes(); @@ -115,6 +120,11 @@ public class MainActivity extends AppCompatActivity { } } + + @Override + public void onDisconnected() { + Log.i(TAG, "Card disconnected."); + } }); cardManager.start(); } diff --git a/lib/src/main/java/im/status/hardwallet_lite_android/wallet/KeyPath.java b/lib/src/main/java/im/status/hardwallet_lite_android/wallet/KeyPath.java index 749191e..5415283 100644 --- a/lib/src/main/java/im/status/hardwallet_lite_android/wallet/KeyPath.java +++ b/lib/src/main/java/im/status/hardwallet_lite_android/wallet/KeyPath.java @@ -26,7 +26,6 @@ public class KeyPath { * @param keypath the keypath as a string */ public KeyPath(String keypath) { - data = new byte[40]; StringTokenizer tokenizer = new StringTokenizer(keypath, "/"); String sourceOrFirstElement = tokenizer.nextToken(); @@ -52,12 +51,23 @@ public class KeyPath { throw new IllegalArgumentException("Too many components"); } + data = new byte[4 * componentCount]; + for (int i = 0; i < componentCount; i++) { long component = parseComponent(tokenizer.nextToken()); writeComponent(component, i); } } + public KeyPath(byte[] data, int source) { + this.data = data; + this.source = source; + } + + public KeyPath(byte[] data) { + this(data, WalletAppletCommandSet.DERIVE_P1_SOURCE_MASTER); + } + private long parseComponent(String num) { long sign; @@ -99,4 +109,37 @@ public class KeyPath { public byte[] getData() { return data; } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + + switch(source) { + case WalletAppletCommandSet.DERIVE_P1_SOURCE_MASTER: + sb.append('m'); + break; + case WalletAppletCommandSet.DERIVE_P1_SOURCE_PARENT: + sb.append(".."); + break; + case WalletAppletCommandSet.DERIVE_P1_SOURCE_CURRENT: + sb.append('.'); + break; + } + + for (int i = 0; i < this.data.length; i += 4) { + sb.append('/'); + appendComponent(sb, i); + } + + return sb.toString(); + } + + private void appendComponent(StringBuffer sb, int i) { + int num = ((this.data[i] & 0x7f) << 24) | ((this.data[i+1] & 0xff) << 16) | ((this.data[i+2] & 0xff) << 8) | (this.data[i+3] & 0xff); + sb.append(num); + + if ((this.data[i] & 0x80) == 0x80) { + sb.append('\''); + } + } } diff --git a/lib/src/main/java/im/status/hardwallet_lite_android/wallet/WalletAppletCommandSet.java b/lib/src/main/java/im/status/hardwallet_lite_android/wallet/WalletAppletCommandSet.java index f9deaea..2c1efe2 100644 --- a/lib/src/main/java/im/status/hardwallet_lite_android/wallet/WalletAppletCommandSet.java +++ b/lib/src/main/java/im/status/hardwallet_lite_android/wallet/WalletAppletCommandSet.java @@ -38,6 +38,7 @@ public class WalletAppletCommandSet { static final byte INS_EXPORT_KEY = (byte) 0xC2; public static final byte GET_STATUS_P1_APPLICATION = 0x00; + public static final byte GET_STATUS_P1_KEY_PATH = 0x01; public static final byte LOAD_KEY_P1_EC = 0x01; public static final byte LOAD_KEY_P1_EXT_EC = 0x02;