use pairing key generated using PBKDF2

This commit is contained in:
Michele Balistreri 2018-09-14 11:35:47 +03:00
parent 7ed8b803df
commit 6af167612e
3 changed files with 34 additions and 10 deletions

View File

@ -63,7 +63,7 @@ task install(type: Exec) {
send_apdu_nostop -sc 1 -APDU 80E400800E4F0C53746174757357616C6C6574
install_for_load -pkgAID 53746174757357616C6C6574
load -file build/javacard/im/status/wallet/javacard/wallet.cap
send_apdu -sc 1 -APDU 80E60C005F0C53746174757357616C6C65740F53746174757357616C6C65744170700F53746174757357616C6C657441707001002EC92C313233343536373839303132178381C5E8D324BED4033D14E1E1FDCAAADB74803869bee9f7a10b1b7108ed5300
send_apdu -sc 1 -APDU 80E60C005F0C53746174757357616C6C65740F53746174757357616C6C65744170700F53746174757357616C6C657441707001002EC92C313233343536373839303132e929d425d7f73c2a0a24ffefad87b65e9b2ee96603eab34d64088b5aae2a026f00
card_disconnect
release_context
"""

View File

@ -60,6 +60,7 @@ public class WalletApplet extends Applet {
static final byte EXPORT_KEY_P1_ANY = 0x00;
static final byte EXPORT_KEY_P1_WHISPER = 0x01;
static final byte EXPORT_KEY_P1_DATABASE = 0x02;
static final byte EXPORT_KEY_P2_PRIVATE_AND_PUBLIC = 0x00;
static final byte EXPORT_KEY_P2_PUBLIC_ONLY = 0x01;
@ -82,7 +83,8 @@ public class WalletApplet extends Applet {
static final byte TLV_UID = (byte) 0x8F;
private static final byte[] ASSISTED_DERIVATION_HASH = {(byte) 0xAA, (byte) 0x2D, (byte) 0xA9, (byte) 0x9D, (byte) 0x91, (byte) 0x8C, (byte) 0x7D, (byte) 0x95, (byte) 0xB8, (byte) 0x96, (byte) 0x89, (byte) 0x87, (byte) 0x3E, (byte) 0xAA, (byte) 0x37, (byte) 0x67, (byte) 0x25, (byte) 0x0C, (byte) 0xFF, (byte) 0x50, (byte) 0x13, (byte) 0x9A, (byte) 0x2F, (byte) 0x87, (byte) 0xBB, (byte) 0x4F, (byte) 0xCA, (byte) 0xB4, (byte) 0xAE, (byte) 0xC3, (byte) 0xE8, (byte) 0x90};
private static final byte[] WHISPER_KEY_PATH = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01};
private static final byte[] WHISPER_KEY_PATH = {(byte) 0x80, 0x00, 0x00, 0x2c, (byte) 0x80, 0x00, 0x00, 0x3c, (byte) 0x80, 0x00, 0x00, 0x00, (byte) 0x00, 0x00, 0x00, 0x00, (byte) 0xC0, 0x00, 0x00, 0x00};
private static final byte[] DATABASE_KEY_PATH = {(byte) 0x80, 0x00, 0x00, 0x2c, (byte) 0x80, 0x00, 0x00, 0x3c, (byte) 0x80, 0x00, 0x00, 0x00, (byte) 0x00, 0x00, 0x00, 0x00, (byte) 0xC0, 0x00, 0x00, 0x01};
private OwnerPIN pin;
private OwnerPIN puk;
@ -954,6 +956,9 @@ public class WalletApplet extends Applet {
case EXPORT_KEY_P1_WHISPER:
toExport = WHISPER_KEY_PATH;
break;
case EXPORT_KEY_P1_DATABASE:
toExport = DATABASE_KEY_PATH;
break;
default:
ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
return;

View File

@ -42,8 +42,8 @@ import static org.junit.jupiter.api.Assertions.*;
@DisplayName("Test the Wallet Applet")
public class WalletAppletTest {
// Generated on https://www.browserling.com/tools/scrypt using Password abc123, Salt WVpJqW4u, Output Size 32, N 16384, r 8, p 1
public static final byte[] SHARED_SECRET = new byte[] { (byte) 0x17, (byte) 0x83, (byte) 0x81, (byte) 0xc5, (byte) 0xe8, (byte) 0xd3, (byte) 0x24, (byte) 0xbe, (byte) 0xd4, (byte) 0x03, (byte) 0x3d, (byte) 0x14, (byte) 0xe1, (byte) 0xe1, (byte) 0xfd, (byte) 0xca, (byte) 0xaa, (byte) 0xdb, (byte) 0x74, (byte) 0x80, (byte) 0x38, (byte) 0x69, (byte) 0xbe, (byte) 0xe9, (byte) 0xf7, (byte) 0xa1, (byte) 0x0b, (byte) 0x1b, (byte) 0x71, (byte) 0x08, (byte) 0xed, (byte) 0x53 };
// 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 };
private static CardTerminal cardTerminal;
private static CardChannel apduChannel;
private static CardSimulator simulator;
@ -843,12 +843,31 @@ public class WalletAppletTest {
response = cmdSet.exportKey(WalletApplet.EXPORT_KEY_P1_WHISPER, false);
assertEquals(0x6985, response.getSW());
response = cmdSet.deriveKey(new byte[] {0x00, 0x00, 0x00, 0x01}, WalletApplet.DERIVE_P1_SOURCE_MASTER, true, false);
response = cmdSet.deriveKey(new byte[] { (byte) 0x80, 0x00, 0x00, 0x2c}, WalletApplet.DERIVE_P1_SOURCE_MASTER, true, false);
assertEquals(0x9000, response.getSW());
response = cmdSet.deriveKey(derivePublicKey(response.getData()), WalletApplet.DERIVE_P1_SOURCE_CURRENT, true, true);
assertEquals(0x9000, response.getSW());
response = cmdSet.exportKey(WalletApplet.EXPORT_KEY_P1_WHISPER, false);
assertEquals(0x6985, response.getSW());
response = cmdSet.deriveKey(new byte[] { (byte) 0x80, 0x00, 0x00, 0x3c}, WalletApplet.DERIVE_P1_SOURCE_CURRENT, true, false);
assertEquals(0x9000, response.getSW());
response = cmdSet.deriveKey(derivePublicKey(response.getData()), WalletApplet.DERIVE_P1_SOURCE_CURRENT, true, true);
assertEquals(0x9000, response.getSW());
response = cmdSet.exportKey(WalletApplet.EXPORT_KEY_P1_WHISPER, false);
assertEquals(0x6985, response.getSW());
response = cmdSet.deriveKey(new byte[] { (byte) 0x80, 0x00, 0x00, 0x00}, WalletApplet.DERIVE_P1_SOURCE_CURRENT, true, false);
assertEquals(0x9000, response.getSW());
response = cmdSet.deriveKey(derivePublicKey(response.getData()), WalletApplet.DERIVE_P1_SOURCE_CURRENT, true, true);
assertEquals(0x9000, response.getSW());
response = cmdSet.exportKey(WalletApplet.EXPORT_KEY_P1_WHISPER, false);
assertEquals(0x6985, response.getSW());
response = cmdSet.deriveKey(new byte[] { (byte) 0x00, 0x00, 0x00, 0x00}, WalletApplet.DERIVE_P1_SOURCE_CURRENT, true, false);
assertEquals(0x9000, response.getSW());
response = cmdSet.deriveKey(derivePublicKey(response.getData()), WalletApplet.DERIVE_P1_SOURCE_CURRENT, true, true);
assertEquals(0x9000, response.getSW());
response = cmdSet.exportKey(WalletApplet.EXPORT_KEY_P1_WHISPER, false);
assertEquals(0x6985, response.getSW());
// Export current public key (wrong P2)
response = cmdSet.exportKey(WalletApplet.EXPORT_KEY_P1_ANY, false);
@ -858,28 +877,28 @@ public class WalletAppletTest {
response = cmdSet.exportKey(WalletApplet.EXPORT_KEY_P1_ANY, true);
assertEquals(0x9000, response.getSW());
byte[] keyTemplate = response.getData();
verifyExportedKey(keyTemplate, keyPair, chainCode, new int[] { 1 }, true);
verifyExportedKey(keyTemplate, keyPair, chainCode, new int[] { 0x8000002c, 0x8000003c, 0x80000000, 0x00000000 }, true);
response = cmdSet.deriveKey(new byte[] {0x00, 0x00, 0x00, 0x01}, WalletApplet.DERIVE_P1_SOURCE_CURRENT, true, false);
response = cmdSet.deriveKey(new byte[] {(byte) 0xC0, 0x00, 0x00, 0x00}, WalletApplet.DERIVE_P1_SOURCE_CURRENT, true, false);
assertEquals(0x9000, response.getSW());
response = cmdSet.deriveKey(derivePublicKey(response.getData()), WalletApplet.DERIVE_P1_SOURCE_CURRENT, true, true);
assertEquals(0x9000, response.getSW());
// Wrong P1
response = cmdSet.exportKey((byte) 2, false);
response = cmdSet.exportKey((byte) 3, false);
assertEquals(0x6a86, response.getSW());
// Correct
response = cmdSet.exportKey(WalletApplet.EXPORT_KEY_P1_WHISPER, false);
assertEquals(0x9000, response.getSW());
keyTemplate = response.getData();
verifyExportedKey(keyTemplate, keyPair, chainCode, new int[] { 1, 1 }, false);
verifyExportedKey(keyTemplate, keyPair, chainCode, new int[] { 0x8000002c, 0x8000003c, 0x80000000, 0x00000000, 0xC0000000 }, false);
// Correct public only
response = cmdSet.exportKey(WalletApplet.EXPORT_KEY_P1_WHISPER, true);
assertEquals(0x9000, response.getSW());
keyTemplate = response.getData();
verifyExportedKey(keyTemplate, keyPair, chainCode, new int[] { 1, 1 }, true);
verifyExportedKey(keyTemplate, keyPair, chainCode, new int[] { 0x8000002c, 0x8000003c, 0x80000000, 0x00000000, 0xC0000000 }, true);
// Reset
response = cmdSet.deriveKey(new byte[] {}, WalletApplet.DERIVE_P1_SOURCE_MASTER, false, false);