add conversion from keypath data to string

This commit is contained in:
Michele Balistreri 2018-11-16 11:12:33 +03:00
parent f646e5d8ee
commit 002ade1c74
3 changed files with 61 additions and 7 deletions

View File

@ -6,8 +6,8 @@ import android.support.v7.app.AppCompatActivity;
import android.util.Log; import android.util.Log;
import im.status.hardwallet_lite_android.demo.R; import im.status.hardwallet_lite_android.demo.R;
import im.status.hardwallet_lite_android.io.CardChannel; 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.CardManager;
import im.status.hardwallet_lite_android.io.OnCardConnectedListener;
import im.status.hardwallet_lite_android.wallet.*; import im.status.hardwallet_lite_android.wallet.*;
import org.spongycastle.util.encoders.Hex; import org.spongycastle.util.encoders.Hex;
@ -25,7 +25,7 @@ public class MainActivity extends AppCompatActivity {
nfcAdapter = NfcAdapter.getDefaultAdapter(this); nfcAdapter = NfcAdapter.getDefaultAdapter(this);
cardManager = new CardManager(); cardManager = new CardManager();
cardManager.setOnCardConnectedListener(new OnCardConnectedListener() { cardManager.setCardListener(new CardListener() {
@Override @Override
public void onConnected(CardChannel cardChannel) { public void onConnected(CardChannel cardChannel) {
try { try {
@ -87,11 +87,16 @@ public class MainActivity extends AppCompatActivity {
cmdSet.generateKey(); cmdSet.generateKey();
} }
// Key derivation is needed to select the desired key. The derived key remains current until a new derive // Get the current key path using GET STATUS
// command is sent (it is not lost on power loss). With GET STATUS one can retrieve the current path. KeyPath currentPath = new KeyPath(cmdSet.getStatus(WalletAppletCommandSet.GET_STATUS_P1_KEY_PATH).checkOK().getData());
cmdSet.deriveKey("m/44'/0'/0'/0/0").checkOK(); Log.i(TAG, "Current key path: " + currentPath);
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"); Log.i(TAG, "Derived m/44'/0'/0'/0/0");
}
byte[] hash = "thiscouldbeahashintheorysoitisok".getBytes(); byte[] hash = "thiscouldbeahashintheorysoitisok".getBytes();
@ -115,6 +120,11 @@ public class MainActivity extends AppCompatActivity {
} }
} }
@Override
public void onDisconnected() {
Log.i(TAG, "Card disconnected.");
}
}); });
cardManager.start(); cardManager.start();
} }

View File

@ -26,7 +26,6 @@ public class KeyPath {
* @param keypath the keypath as a string * @param keypath the keypath as a string
*/ */
public KeyPath(String keypath) { public KeyPath(String keypath) {
data = new byte[40];
StringTokenizer tokenizer = new StringTokenizer(keypath, "/"); StringTokenizer tokenizer = new StringTokenizer(keypath, "/");
String sourceOrFirstElement = tokenizer.nextToken(); String sourceOrFirstElement = tokenizer.nextToken();
@ -52,12 +51,23 @@ public class KeyPath {
throw new IllegalArgumentException("Too many components"); throw new IllegalArgumentException("Too many components");
} }
data = new byte[4 * componentCount];
for (int i = 0; i < componentCount; i++) { for (int i = 0; i < componentCount; i++) {
long component = parseComponent(tokenizer.nextToken()); long component = parseComponent(tokenizer.nextToken());
writeComponent(component, i); 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) { private long parseComponent(String num) {
long sign; long sign;
@ -99,4 +109,37 @@ public class KeyPath {
public byte[] getData() { public byte[] getData() {
return data; 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('\'');
}
}
} }

View File

@ -38,6 +38,7 @@ public class WalletAppletCommandSet {
static final byte INS_EXPORT_KEY = (byte) 0xC2; static final byte INS_EXPORT_KEY = (byte) 0xC2;
public static final byte GET_STATUS_P1_APPLICATION = 0x00; 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_EC = 0x01;
public static final byte LOAD_KEY_P1_EXT_EC = 0x02; public static final byte LOAD_KEY_P1_EXT_EC = 0x02;