make EXPORT KEY able to derive from other sources
This commit is contained in:
parent
98ffcda1b8
commit
d4e01ab21b
|
@ -439,7 +439,9 @@ private key (P2=0x00) can be exported if and only if the requested key path is i
|
|||
|
||||
The P1 parameter indicates how to the derive the desired key. P1 = 0x00 indicates that the current key must be exported,
|
||||
and no derivation will be performed. P1 = 0x01 derives the path given in the data field without changing the current
|
||||
path of the card. P1 = 0x02 derives the path but also changes the current path of the card.
|
||||
path of the card. P1 = 0x02 derives the path but also changes the current path of the card. The source for derivation
|
||||
can be set by OR'ing P1 with the constants defined in the DERIVE KEY command. This allows deriving from master, parent
|
||||
or current.
|
||||
|
||||
If the private key is being exported, the card could omit exporting the public key for performance reason. The public
|
||||
key can then be calculate off-card if needed.
|
|
@ -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:75d9f54")
|
||||
testCompile("com.github.status-im:hardwallet-lite-sdk:482e32c")
|
||||
testCompile("org.junit.jupiter:junit-jupiter-api:5.1.1")
|
||||
testRuntime("org.junit.jupiter:junit-jupiter-engine:5.1.1")
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ public class WalletApplet extends Applet {
|
|||
static final byte DERIVE_P1_SOURCE_MASTER = (byte) 0x00;
|
||||
static final byte DERIVE_P1_SOURCE_PARENT = (byte) 0x40;
|
||||
static final byte DERIVE_P1_SOURCE_CURRENT = (byte) 0x80;
|
||||
static final byte DERIVE_P1_SOURCE_MASK = (byte) 0xC0;
|
||||
|
||||
static final byte GENERATE_MNEMONIC_P1_CS_MIN = 4;
|
||||
static final byte GENERATE_MNEMONIC_P1_CS_MAX = 8;
|
||||
|
@ -1233,25 +1234,26 @@ public class WalletApplet extends Applet {
|
|||
return;
|
||||
}
|
||||
|
||||
byte[] exportPath;
|
||||
short exportPathOff;
|
||||
short exportPathLen;
|
||||
byte[] exportPath = keyPath;
|
||||
short exportPathOff = (short) 0;
|
||||
short exportPathLen = keyPathLen;
|
||||
|
||||
boolean derive = false;
|
||||
boolean makeCurrent = false;
|
||||
byte derivationSource = (byte) (apduBuffer[ISO7816.OFFSET_P1] & DERIVE_P1_SOURCE_MASK);
|
||||
|
||||
switch (apduBuffer[ISO7816.OFFSET_P1]) {
|
||||
switch ((byte) (apduBuffer[ISO7816.OFFSET_P1] & ~DERIVE_P1_SOURCE_MASK)) {
|
||||
case EXPORT_KEY_P1_CURRENT:
|
||||
exportPath = keyPath;
|
||||
exportPathOff = (short) 0;
|
||||
exportPathLen = keyPathLen;
|
||||
break;
|
||||
case EXPORT_KEY_P1_DERIVE_AND_MAKE_CURRENT:
|
||||
makeCurrent = true;
|
||||
case EXPORT_KEY_P1_DERIVE:
|
||||
derive = true;
|
||||
exportPath = apduBuffer;
|
||||
exportPathOff = ISO7816.OFFSET_CDATA;
|
||||
exportPathLen = dataLen;
|
||||
if (derivationSource == DERIVE_P1_SOURCE_MASTER) {
|
||||
exportPath = apduBuffer;
|
||||
exportPathOff = ISO7816.OFFSET_CDATA;
|
||||
exportPathLen = dataLen;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
|
||||
|
@ -1263,7 +1265,7 @@ public class WalletApplet extends Applet {
|
|||
}
|
||||
|
||||
if (derive) {
|
||||
doDerive(apduBuffer, dataLen, DERIVE_P1_SOURCE_MASTER, makeCurrent);
|
||||
doDerive(apduBuffer, dataLen, derivationSource, makeCurrent);
|
||||
}
|
||||
|
||||
short off = SecureChannel.SC_OUT_OFFSET;
|
||||
|
|
|
@ -981,13 +981,13 @@ 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}, 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}, WalletApplet.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) 0x80, 0x00, 0x00, 0x2B, (byte) 0x80, 0x00, 0x00, 0x3C, (byte) 0x80, 0x00, 0x06, 0x2D, (byte) 0x00, 0x00, 0x00, 0x00, (byte) 0x00, 0x00, 0x00, 0x01}, false,false);
|
||||
response = cmdSet.exportKey(new byte[] {(byte) 0x00, 0x00, 0x00, 0x01}, WalletApplet.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);
|
||||
|
@ -1002,7 +1002,7 @@ public class WalletAppletTest {
|
|||
verifyExportedKey(keyTemplate, keyPair, chainCode, new int[] { 0x8000002b, 0x8000003c, 0x8000062d, 0x00000000, 0x00000000 }, false, false);
|
||||
|
||||
// Reset
|
||||
response = cmdSet.deriveKey(new byte[] {}, WalletApplet.DERIVE_P1_SOURCE_MASTER);
|
||||
response = cmdSet.deriveKey(new byte[0], WalletApplet.DERIVE_P1_SOURCE_MASTER);
|
||||
assertEquals(0x9000, response.getSW());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue