add sign and derive tests

This commit is contained in:
Michele Balistreri 2019-04-01 17:06:20 +03:00
parent 5bc5e23272
commit 355ee91d2c
3 changed files with 57 additions and 12 deletions

View File

@ -54,7 +54,7 @@ dependencies {
testCompile(files("../jcardsim/jcardsim-3.0.5-SNAPSHOT.jar")) testCompile(files("../jcardsim/jcardsim-3.0.5-SNAPSHOT.jar"))
testCompile('org.web3j:core:2.3.1') testCompile('org.web3j:core:2.3.1')
testCompile('org.bitcoinj:bitcoinj-core:0.14.5') testCompile('org.bitcoinj:bitcoinj-core:0.14.5')
testCompile('com.github.status-im.status-keycard-java:desktop:425d085') testCompile('com.github.status-im.status-keycard-java:desktop:4ec4e07')
testCompile('org.bouncycastle:bcprov-jdk15on:1.60') testCompile('org.bouncycastle:bcprov-jdk15on:1.60')
testCompile("org.junit.jupiter:junit-jupiter-api:5.1.1") testCompile("org.junit.jupiter:junit-jupiter-api:5.1.1")
testRuntime("org.junit.jupiter:junit-jupiter-engine:5.1.1") testRuntime("org.junit.jupiter:junit-jupiter-engine:5.1.1")

View File

@ -924,7 +924,7 @@ public class KeycardApplet extends Applet {
secp256k1.derivePublicKey(privateKey, apduBuffer, scratchOff); secp256k1.derivePublicKey(privateKey, apduBuffer, scratchOff);
publicKey.setW(apduBuffer, scratchOff, Crypto.KEY_PUB_SIZE); publicKey.setW(apduBuffer, scratchOff, Crypto.KEY_PUB_SIZE);
Util.arrayCopy(apduBuffer, ISO7816.OFFSET_CDATA, keyPath, pathLenOff, len); Util.arrayCopy(apduBuffer, pathOff, keyPath, pathLenOff, len);
keyPathLen = newPathLen; keyPathLen = newPathLen;
JCSystem.commitTransaction(); JCSystem.commitTransaction();
} }
@ -1255,7 +1255,8 @@ public class KeycardApplet extends Applet {
ISOException.throwIt(ISO7816.SW_WRONG_DATA); ISOException.throwIt(ISO7816.SW_WRONG_DATA);
} }
doDerive(apduBuffer, MessageDigest.LENGTH_SHA_256, pathLen, apduBuffer[ISO7816.OFFSET_P1], makeCurrent); byte derivationSource = (byte) (apduBuffer[ISO7816.OFFSET_P1] & DERIVE_P1_SOURCE_MASK);
doDerive(apduBuffer, MessageDigest.LENGTH_SHA_256, pathLen, derivationSource, makeCurrent);
} else { } else {
if (len != MessageDigest.LENGTH_SHA_256) { if (len != MessageDigest.LENGTH_SHA_256) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA); ISOException.throwIt(ISO7816.SW_WRONG_DATA);
@ -1466,7 +1467,7 @@ public class KeycardApplet extends Applet {
secp256k1.setCurveParameters(publicKey); secp256k1.setCurveParameters(publicKey);
secp256k1.setCurveParameters(privateKey); secp256k1.setCurveParameters(privateKey);
secp256k1.setCurveParameters(pinlessPrivateKey);
secp256k1.setCurveParameters(pinlessPublicKey); secp256k1.setCurveParameters(pinlessPublicKey);
secp256k1.setCurveParameters(pinlessPrivateKey);
} }
} }

View File

@ -37,11 +37,11 @@ import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.security.KeyFactory; import java.security.*;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Signature;
import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.interfaces.ECPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Random; import java.util.Random;
@ -1002,11 +1002,8 @@ public class KeycardTest {
assertEquals(0x9000, response.getSw()); assertEquals(0x9000, response.getSw());
} }
Signature signature = Signature.getInstance("SHA256withECDSA", "BC");
if (!cmdSet.getApplicationInfo().hasMasterKey()) { if (!cmdSet.getApplicationInfo().hasMasterKey()) {
KeyPair keyPair = keypairGenerator().generateKeyPair(); response = cmdSet.generateKey();
response = cmdSet.loadKey(keyPair);
assertEquals(0x9000, response.getSw()); assertEquals(0x9000, response.getSw());
} }
@ -1016,6 +1013,53 @@ public class KeycardTest {
// Correctly sign a precomputed hash // Correctly sign a precomputed hash
response = cmdSet.sign(hash); response = cmdSet.sign(hash);
verifySignResp(data, response);
// Sign and derive
String currentPath = new KeyPath(cmdSet.getStatus(KeycardCommandSet.GET_STATUS_P1_KEY_PATH).checkOK().getData()).toString();
String updatedPath = new KeyPath(currentPath + "/2").toString();
response = cmdSet.signWithPath(hash, updatedPath, false);
verifySignResp(data, response);
assertEquals(currentPath, new KeyPath(cmdSet.getStatus(KeycardCommandSet.GET_STATUS_P1_KEY_PATH).checkOK().getData()).toString());
response = cmdSet.signWithPath(hash, updatedPath, true);
verifySignResp(data, response);
assertEquals(updatedPath, new KeyPath(cmdSet.getStatus(KeycardCommandSet.GET_STATUS_P1_KEY_PATH).checkOK().getData()).toString());
// Sign with PINless
String pinlessPath = currentPath + "/3";
response = cmdSet.setPinlessPath(pinlessPath);
assertEquals(0x9000, response.getSw());
// No secure channel or PIN auth
reset();
response = cmdSet.select();
assertEquals(0x9000, response.getSw());
response = cmdSet.signPinless(hash);
verifySignResp(data, response);
// With secure channel
if (cmdSet.getApplicationInfo().hasSecureChannelCapability()) {
cmdSet.autoOpenSecureChannel();
response = cmdSet.signPinless(hash);
verifySignResp(data, response);
}
// No pinless path
if (cmdSet.getApplicationInfo().hasCredentialsManagementCapability()) {
response = cmdSet.verifyPIN("000000");
assertEquals(0x9000, response.getSw());
}
response = cmdSet.resetPinlessPath();
assertEquals(0x9000, response.getSw());
response = cmdSet.signPinless(hash);
assertEquals(0x6985, response.getSw());
}
private void verifySignResp(byte[] data, APDUResponse response) throws Exception {
Signature signature = Signature.getInstance("SHA256withECDSA", "BC");
assertEquals(0x9000, response.getSw()); assertEquals(0x9000, response.getSw());
byte[] sig = response.getData(); byte[] sig = response.getData();
byte[] keyData = extractPublicKeyFromSignature(sig); byte[] keyData = extractPublicKeyFromSignature(sig);