JCOP4 workaround (defer initialization)
This commit is contained in:
parent
bca030f069
commit
1d16a82117
|
@ -64,11 +64,11 @@ public class InstallTask extends DefaultTask {
|
|||
}
|
||||
});
|
||||
logger.info("Installing the Keycard Applet");
|
||||
cmdSet.installKeycardApplet();
|
||||
cmdSet.installKeycardApplet().checkOK();
|
||||
logger.info("Installing the NDEF Applet");
|
||||
cmdSet.installNDEFApplet(new byte[0]);
|
||||
cmdSet.installNDEFApplet(new byte[0]).checkOK();
|
||||
logger.info("Installing the Cash Applet");
|
||||
cmdSet.installCashApplet();
|
||||
cmdSet.installCashApplet().checkOK();
|
||||
} catch (IOException e) {
|
||||
throw new GradleException("I/O error", e);
|
||||
} catch (APDUException e) {
|
||||
|
|
|
@ -40,7 +40,7 @@ public class CashApplet extends Applet {
|
|||
*/
|
||||
public CashApplet(byte[] bArray, short bOffset, byte bLength) {
|
||||
crypto = new Crypto();
|
||||
secp256k1 = new SECP256k1(crypto);
|
||||
secp256k1 = new SECP256k1();
|
||||
|
||||
keypair = new KeyPair(KeyPair.ALG_EC_FP, SECP256k1.SECP256K1_KEY_SIZE);
|
||||
publicKey = (ECPublicKey) keypair.getPublic();
|
||||
|
|
|
@ -167,8 +167,7 @@ public class KeycardApplet extends Applet {
|
|||
*/
|
||||
public KeycardApplet(byte[] bArray, short bOffset, byte bLength) {
|
||||
crypto = new Crypto();
|
||||
secp256k1 = new SECP256k1(crypto);
|
||||
secureChannel = new SecureChannel(PAIRING_MAX_CLIENT_COUNT, crypto, secp256k1);
|
||||
secp256k1 = new SECP256k1();
|
||||
|
||||
uid = new byte[UID_LENGTH];
|
||||
crypto.random.generateData(uid, (short) 0, UID_LENGTH);
|
||||
|
@ -199,7 +198,7 @@ public class KeycardApplet extends Applet {
|
|||
|
||||
derivationOutput = JCSystem.makeTransientByteArray((short) (Crypto.KEY_SECRET_SIZE + CHAIN_CODE_SIZE), JCSystem.CLEAR_ON_RESET);
|
||||
|
||||
data = new byte[MAX_DATA_LENGTH + 1];
|
||||
data = new byte[(short)(MAX_DATA_LENGTH + 1)];
|
||||
|
||||
register(bArray, (short) (bOffset + 1), bArray[bOffset]);
|
||||
}
|
||||
|
@ -214,6 +213,9 @@ public class KeycardApplet extends Applet {
|
|||
public void process(APDU apdu) throws ISOException {
|
||||
// If we have no PIN it means we still have to initialize the applet.
|
||||
if (pin == null) {
|
||||
if (secureChannel == null) {
|
||||
secureChannel = new SecureChannel(PAIRING_MAX_CLIENT_COUNT, crypto, secp256k1);
|
||||
}
|
||||
processInit(apdu);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -54,14 +54,12 @@ public class SECP256k1 {
|
|||
|
||||
|
||||
private KeyAgreement ecPointMultiplier;
|
||||
private Crypto crypto;
|
||||
ECPrivateKey tmpECPrivateKey;
|
||||
|
||||
/**
|
||||
* Allocates objects needed by this class. Must be invoked during the applet installation exactly 1 time.
|
||||
*/
|
||||
SECP256k1(Crypto crypto) {
|
||||
this.crypto = crypto;
|
||||
SECP256k1() {
|
||||
this.ecPointMultiplier = KeyAgreement.getInstance(ALG_EC_SVDP_DH_PLAIN_XY, false);
|
||||
this.tmpECPrivateKey = (ECPrivateKey) KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PRIVATE, SECP256K1_KEY_SIZE, false);
|
||||
setCurveParameters(tmpECPrivateKey);
|
||||
|
|
|
@ -56,13 +56,14 @@ public class SecureChannel {
|
|||
scEncKey = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES_TRANSIENT_DESELECT, KeyBuilder.LENGTH_AES_256, false);
|
||||
scMacKey = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES_TRANSIENT_DESELECT, KeyBuilder.LENGTH_AES_256, false);
|
||||
|
||||
secret = JCSystem.makeTransientByteArray((short)(SC_SECRET_LENGTH * 2), JCSystem.CLEAR_ON_DESELECT);
|
||||
pairingKeys = new byte[(short)(PAIRING_KEY_LENGTH * pairingLimit)];
|
||||
|
||||
scKeypair = new KeyPair(KeyPair.ALG_EC_FP, SC_KEY_LENGTH);
|
||||
secp256k1.setCurveParameters((ECKey) scKeypair.getPrivate());
|
||||
secp256k1.setCurveParameters((ECKey) scKeypair.getPublic());
|
||||
scKeypair.genKeyPair();
|
||||
|
||||
secret = JCSystem.makeTransientByteArray((short)(SC_SECRET_LENGTH * 2), JCSystem.CLEAR_ON_DESELECT);
|
||||
pairingKeys = new byte[(short)(PAIRING_KEY_LENGTH * pairingLimit)];
|
||||
remainingSlots = pairingLimit;
|
||||
|
||||
}
|
||||
|
|
|
@ -289,19 +289,7 @@ public class KeycardTest {
|
|||
response = cmdSet.getStatus(KeycardApplet.GET_STATUS_P1_APPLICATION);
|
||||
assertEquals(0x9000, response.getSw());
|
||||
|
||||
// Verify that the keys are changed correctly. Since we do not know the internal counter we just iterate until that
|
||||
// happens for a maximum of SC_COUNTER_MAX times
|
||||
byte[] initialKey = new ApplicationInfo(cmdSet.select().getData()).getSecureChannelPubKey();
|
||||
|
||||
for (int i = 0; i < SecureChannel.SC_COUNTER_MAX; i++) {
|
||||
byte[] otherKey = new ApplicationInfo(cmdSet.select().getData()).getSecureChannelPubKey();
|
||||
|
||||
if (!Arrays.equals(initialKey, otherKey)) {
|
||||
secureChannel.generateSecret(otherKey);
|
||||
cmdSet.autoOpenSecureChannel();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -384,7 +372,7 @@ public class KeycardTest {
|
|||
cmdSet.openSecureChannel(secureChannel.getPairingIndex(), secureChannel.getPublicKey());
|
||||
|
||||
// Pair multiple indexes
|
||||
for (int i = 1; i < 5; i++) {
|
||||
for (int i = 1; i < KeycardApplet.PAIRING_MAX_CLIENT_COUNT; i++) {
|
||||
cmdSet.autoPair(sharedSecret);
|
||||
assertEquals(i, secureChannel.getPairingIndex());
|
||||
cmdSet.autoOpenSecureChannel();
|
||||
|
@ -403,7 +391,7 @@ public class KeycardTest {
|
|||
assertEquals(0x9000, response.getSw());
|
||||
}
|
||||
|
||||
for (byte i = 0; i < 4; i++) {
|
||||
for (byte i = 0; i < (KeycardApplet.PAIRING_MAX_CLIENT_COUNT - 1); i++) {
|
||||
response = cmdSet.unpair(i);
|
||||
assertEquals(0x9000, response.getSw());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue