Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
bitgamma committed Nov 10, 2022
1 parent 8ac2e88 commit b55764b
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 34 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ buildscript {

dependencies {
classpath 'com.fidesmo:gradle-javacard:0.2.7'
classpath 'com.github.status-im.status-keycard-java:desktop:31f4ab5'
classpath 'com.github.status-im.status-keycard-java:desktop:7d968cf'
}
}

Expand Down Expand Up @@ -59,7 +59,7 @@ dependencies {
testCompile(files("../jcardsim/jcardsim-3.0.5-SNAPSHOT.jar"))
testCompile('org.web3j:core:2.3.1')
testCompile('org.bitcoinj:bitcoinj-core:0.14.5')
testCompile('com.github.status-im.status-keycard-java:desktop:31f4ab5')
testCompile('com.github.status-im.status-keycard-java:desktop:7d968cf')
testCompile('org.bouncycastle:bcprov-jdk15on:1.65')
testCompile("org.junit.jupiter:junit-jupiter-api:5.1.1")
testRuntime("org.junit.jupiter:junit-jupiter-engine:5.1.1")
Expand Down
2 changes: 1 addition & 1 deletion buildSrc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ repositories {
}

dependencies {
compile 'com.github.status-im.status-keycard-java:desktop:31f4ab5'
compile 'com.github.status-im.status-keycard-java:desktop:7d968cf'
}
35 changes: 18 additions & 17 deletions src/main/java/im/status/keycard/KeycardApplet.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ public class KeycardApplet extends Applet {
static final byte[] EIP_1581_PREFIX = { (byte) 0x80, 0x00, 0x00, 0x2B, (byte) 0x80, 0x00, 0x00, 0x3C, (byte) 0x80, 0x00, 0x06, 0x2D};

private OwnerPIN pin;
private OwnerPIN realPin;
private OwnerPIN fakePin;
private OwnerPIN mainPIN;
private OwnerPIN altPIN;
private OwnerPIN puk;
private byte[] uid;
private SecureChannel secureChannel;
Expand Down Expand Up @@ -347,16 +347,16 @@ private void processInit(APDU apdu) {

secureChannel.initSecureChannel(apduBuffer, (short)(ISO7816.OFFSET_CDATA + PIN_LENGTH + PUK_LENGTH));

realPin = new OwnerPIN(pinLimit, PIN_LENGTH);
realPin.update(apduBuffer, ISO7816.OFFSET_CDATA, PIN_LENGTH);
mainPIN = new OwnerPIN(pinLimit, PIN_LENGTH);
mainPIN.update(apduBuffer, ISO7816.OFFSET_CDATA, PIN_LENGTH);

fakePin = new OwnerPIN(pinLimit, PIN_LENGTH);
fakePin.update(apduBuffer, (short)(ISO7816.OFFSET_CDATA + PIN_LENGTH), PIN_LENGTH);
altPIN = new OwnerPIN(pinLimit, PIN_LENGTH);
altPIN.update(apduBuffer, (short)(ISO7816.OFFSET_CDATA + PIN_LENGTH), PIN_LENGTH);

puk = new OwnerPIN(pukLimit, PUK_LENGTH);
puk.update(apduBuffer, (short)(ISO7816.OFFSET_CDATA + PIN_LENGTH), PUK_LENGTH);

pin = realPin;
pin = mainPIN;
} else if (apduBuffer[ISO7816.OFFSET_INS] == IdentApplet.INS_IDENTIFY_CARD) {
IdentApplet.identifyCard(apdu, null, signature);
} else {
Expand Down Expand Up @@ -392,10 +392,11 @@ private void unpair(APDU apdu) {
* @param apdu the JCRE-owned APDU object.
*/
private void selectApplet(APDU apdu) {
fakePin.reset();
realPin.reset();
altPIN.reset();
mainPIN.reset();
puk.reset();
secureChannel.reset();
pin = mainPIN;

byte[] apduBuffer = apdu.getBuffer();

Expand Down Expand Up @@ -524,23 +525,23 @@ private void verifyPIN(APDU apdu) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
}

short resp = realPin.check(apduBuffer, ISO7816.OFFSET_CDATA, len) ? (short) 1 : (short) 0;
resp += fakePin.check(apduBuffer, ISO7816.OFFSET_CDATA, len) ? (short) 2 : (short) 0;
short resp = mainPIN.check(apduBuffer, ISO7816.OFFSET_CDATA, len) ? (short) 1 : (short) 0;
resp += altPIN.check(apduBuffer, ISO7816.OFFSET_CDATA, len) ? (short) 2 : (short) 0;

switch(resp) {
case 0:
ISOException.throwIt((short)((short) 0x63c0 | (short) pin.getTriesRemaining()));
break;
case 1:
chainCode = masterChainCode;
fakePin.resetAndUnblock();
pin = realPin;
altPIN.resetAndUnblock();
pin = mainPIN;
break;
case 2:
case 3: // if pins are equal fake pin takes precedence
chainCode = fakeChainCode;
realPin.resetAndUnblock();
pin = fakePin;
mainPIN.resetAndUnblock();
pin = altPIN;
break;
}
}
Expand Down Expand Up @@ -639,8 +640,8 @@ private void unblockPIN(APDU apdu) {
ISOException.throwIt((short)((short) 0x63c0 | (short) puk.getTriesRemaining()));
}

fakePin.resetAndUnblock();
realPin.resetAndUnblock();
altPIN.resetAndUnblock();
mainPIN.resetAndUnblock();
pin.update(apduBuffer, (short)(ISO7816.OFFSET_CDATA + PUK_LENGTH), PIN_LENGTH);
pin.check(apduBuffer, (short)(ISO7816.OFFSET_CDATA + PUK_LENGTH), PIN_LENGTH);
puk.reset();
Expand Down
52 changes: 48 additions & 4 deletions src/test/java/im/status/keycard/KeycardTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,10 @@ void verifyPinTest() throws Exception {
response = cmdSet.verifyPIN("000000");
assertEquals(0x9000, response.getSw());

// Alt PIN
response = cmdSet.verifyPIN("012345");
assertEquals(0x9000, response.getSw());

// Check max retry counter
response = cmdSet.verifyPIN("123456");
assertEquals(0x63C2, response.getSw());
Expand All @@ -580,8 +584,11 @@ void verifyPinTest() throws Exception {
response = cmdSet.verifyPIN("000000");
assertEquals(0x63C0, response.getSw());

response = cmdSet.verifyPIN("012345");
assertEquals(0x63C0, response.getSw());

// Unblock PIN to make further tests possible
response = cmdSet.unblockPIN("012345678901", "000000");
response = cmdSet.unblockPIN("012345678901", "012345");
assertEquals(0x9000, response.getSw());
}

Expand All @@ -595,7 +602,7 @@ void changePinTest() throws Exception {

cmdSet.autoOpenSecureChannel();

// Security condition violation: PIN n ot verified
// Security condition violation: PIN not verified
response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_USER_PIN, "123456");
assertEquals(0x6985, response.getSw());

Expand Down Expand Up @@ -687,6 +694,26 @@ void changePinTest() throws Exception {

response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_PAIRING_SECRET, sharedSecret);
assertEquals(0x9000, response.getSw());

// Alt PIN
response = cmdSet.verifyPIN("012345");
assertEquals(0x9000, response.getSw());

response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_USER_PIN, "123456");
assertEquals(0x9000, response.getSw());

resetAndSelectAndOpenSC();

response = cmdSet.verifyPIN("123456");
assertEquals(0x9000, response.getSw());

response = cmdSet.changePIN(KeycardApplet.CHANGE_PIN_P1_USER_PIN, "012345");
assertEquals(0x9000, response.getSw());

resetAndSelectAndOpenSC();

response = cmdSet.verifyPIN("000000");
assertEquals(0x9000, response.getSw());
}

@Test
Expand Down Expand Up @@ -1100,6 +1127,13 @@ void signTest() throws Exception {

response = cmdSet.signPinless(hash);
assertEquals(0x6A88, response.getSw());

// Alt PIN
response = cmdSet.verifyPIN("012345");
assertEquals(0x9000, response.getSw());

response = cmdSet.signWithPath(hash, updatedPath, false);
verifySignResp(data, response);
}

private void verifySignResp(byte[] data, APDUResponse response) throws Exception {
Expand Down Expand Up @@ -1305,17 +1339,27 @@ void exportKey() throws Exception {
verifyExportedKey(keyTemplate, keyPair, chainCode, new int[] { 0x8000002b, 0x8000003c, 0x8000062d, 0x00000000, 0x00000000 }, false, false);

// Export extended public
response = cmdSet.exportExtendedPublicKey(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);
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, false, KeycardCommandSet.EXPORT_KEY_P2_EXTENDED_PUBLIC);
assertEquals(0x6985, response.getSw());

response = cmdSet.exportExtendedPublicKey(new byte[] {(byte) 0x80, 0x00, 0x00, 0x2B, (byte) 0x80, 0x00, 0x00, 0x3C, (byte) 0x80, 0x00, 0x06, 0x2c, (byte) 0x00, 0x00, 0x00, 0x00}, KeycardApplet.DERIVE_P1_SOURCE_MASTER);
response = cmdSet.exportKey(new byte[] {(byte) 0x80, 0x00, 0x00, 0x2B, (byte) 0x80, 0x00, 0x00, 0x3C, (byte) 0x80, 0x00, 0x06, 0x2c, (byte) 0x00, 0x00, 0x00, 0x00}, KeycardApplet.DERIVE_P1_SOURCE_MASTER, false, KeycardCommandSet.EXPORT_KEY_P2_EXTENDED_PUBLIC);
assertEquals(0x9000, response.getSw());
keyTemplate = response.getData();
verifyExportedKey(keyTemplate, keyPair, chainCode, new int[] { 0x8000002b, 0x8000003c, 0x8000062c, 0x00000000 }, true, true);

// Reset
response = cmdSet.deriveKey(new byte[0], KeycardApplet.DERIVE_P1_SOURCE_MASTER);
assertEquals(0x9000, response.getSw());

// Alt PIN
response = cmdSet.verifyPIN("012345");
assertEquals(0x9000, response.getSw());

response = cmdSet.exportKey(new byte[] {(byte) 0x80, 0x00, 0x00, 0x2B, (byte) 0x80, 0x00, 0x00, 0x3C, (byte) 0x80, 0x00, 0x06, 0x2c, (byte) 0x00, 0x00, 0x00, 0x00}, KeycardApplet.DERIVE_P1_SOURCE_MASTER, false, KeycardCommandSet.EXPORT_KEY_P2_EXTENDED_PUBLIC);
assertEquals(0x9000, response.getSw());
keyTemplate = response.getData();
verifyExportedKey(keyTemplate, keyPair, sha256(chainCode), new int[] { 0x8000002b, 0x8000003c, 0x8000062c, 0x00000000 }, true, true);

}

@Test
Expand Down
10 changes: 0 additions & 10 deletions src/test/java/im/status/keycard/TestKeycardCommandSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,12 @@


public class TestKeycardCommandSet extends KeycardCommandSet {
private CardChannel ac;
private TestSecureChannelSession sc;

public TestKeycardCommandSet(CardChannel apduChannel) {
super(apduChannel);
ac = apduChannel;
}

public void setSecureChannel(TestSecureChannelSession secureChannel) {
super.setSecureChannel(secureChannel);
sc = secureChannel;
}

/**
Expand Down Expand Up @@ -83,11 +78,6 @@ public APDUResponse loadKey(PrivateKey aPrivate, byte[] chainCode) throws IOExce
return loadKey(data, LOAD_KEY_P1_SEED);
}

public APDUResponse exportExtendedPublicKey(byte[] keyPath, byte source) throws IOException {
APDUCommand exportKey = sc.protectedCommand(0x80, 0xc2, (source | 0x01), 2, keyPath);
return sc.transmit(ac, exportKey);
}

/**
* Sends a GET STATUS APDU to retrieve the APPLICATION STATUS template and reads the byte indicating key initialization
* status
Expand Down

0 comments on commit b55764b

Please sign in to comment.