add initial Installer class
This commit is contained in:
parent
d5301304eb
commit
a8e2f27624
|
@ -0,0 +1,22 @@
|
|||
package im.status.applet_installer_test.appletinstaller;
|
||||
|
||||
import android.nfc.tech.IsoDep;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import im.status.applet_installer_test.appletinstaller.CardManager;
|
||||
|
||||
public class CardChannel implements Channel {
|
||||
private IsoDep isoDep;
|
||||
|
||||
public CardChannel(IsoDep isoDep) {
|
||||
this.isoDep = isoDep;
|
||||
}
|
||||
|
||||
public byte[] transceive(byte[] data) throws IOException {
|
||||
Logger.log(String.format("COMMAND %s %n", HexUtils.byteArrayToHexString(data)));
|
||||
byte[] resp = this.isoDep.transceive(data);
|
||||
Logger.log(String.format("RESPONSE %s %n", HexUtils.byteArrayToHexString(resp)));
|
||||
return resp;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package im.status.applet_installer_test.appletinstaller;
|
||||
|
||||
import android.nfc.Tag;
|
||||
import android.nfc.tech.IsoDep;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class CardManager {
|
||||
private Tag tag;
|
||||
private IsoDep isoDep;
|
||||
|
||||
public CardManager(Tag tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public void connect() throws IOException {
|
||||
this.isoDep = IsoDep.get(tag);
|
||||
this.isoDep.connect();
|
||||
}
|
||||
|
||||
public void install() throws IOException, APDUException {
|
||||
CardChannel ch = new CardChannel(this.isoDep);
|
||||
Installer installer = new Installer(ch);
|
||||
installer.start();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package im.status.applet_installer_test.appletinstaller;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface Channel {
|
||||
byte[] transceive(byte[] data) throws IOException;
|
||||
}
|
|
@ -15,7 +15,6 @@ import javax.crypto.spec.SecretKeySpec;
|
|||
|
||||
|
||||
public class Crypto {
|
||||
|
||||
public static final byte[] NullBytes8 = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
public static byte[] deriveKey(byte[] cardKey, byte[] seq, byte[] purposeData) {
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package im.status.applet_installer_test.appletinstaller;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import im.status.applet_installer_test.appletinstaller.apducommands.InitializeUpdate;
|
||||
|
||||
public class Installer {
|
||||
private Channel channel;
|
||||
|
||||
static final byte[] cardKeyData = HexUtils.hexStringToByteArray("404142434445464748494a4b4c4d4e4f");
|
||||
|
||||
private Keys cardKeys;
|
||||
|
||||
public Installer(Channel channel) {
|
||||
this.channel = channel;
|
||||
this.cardKeys = new Keys(cardKeyData, cardKeyData);
|
||||
}
|
||||
|
||||
public void start() throws IOException, APDUException {
|
||||
SecureRandom random = new SecureRandom();
|
||||
byte hostChallenge[] = new byte[8];
|
||||
random.nextBytes(hostChallenge);
|
||||
InitializeUpdate init = new InitializeUpdate(hostChallenge);
|
||||
byte[] data = init.getCommand().serialize();
|
||||
|
||||
// get data
|
||||
//byte[] data = new byte[]{(byte) 0x80, (byte) 0xCA, 0x00, (byte) 0x66};
|
||||
|
||||
byte[] respData = this.channel.transceive(data);
|
||||
APDUResponse resp = new APDUResponse(respData);
|
||||
Logger.log(respData);
|
||||
|
||||
Keys keys = init.verifyResponse(this.cardKeys, resp);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package im.status.applet_installer_test.appletinstaller;
|
||||
|
||||
public class Keys {
|
||||
public byte[] encKeyData;
|
||||
public byte[] macKeyData;
|
||||
|
||||
public Keys(byte[] encKeyData, byte[] macKeyData) {
|
||||
this.encKeyData = encKeyData;
|
||||
this.macKeyData = macKeyData;
|
||||
}
|
||||
|
||||
public byte[] getEncKeyData() {
|
||||
return encKeyData;
|
||||
}
|
||||
|
||||
public byte[] getMacKeyData() {
|
||||
return macKeyData;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package im.status.applet_installer_test.appletinstaller;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class Logger {
|
||||
public static void log(String m) {
|
||||
Log.d("installer-debug", m);
|
||||
}
|
||||
|
||||
public static void log(byte[] m) {
|
||||
Log.d("installer-debug", HexUtils.byteArrayToHexString(m));
|
||||
}
|
||||
}
|
|
@ -7,6 +7,8 @@ import im.status.applet_installer_test.appletinstaller.APDUException;
|
|||
import im.status.applet_installer_test.appletinstaller.APDUResponse;
|
||||
import im.status.applet_installer_test.appletinstaller.Crypto;
|
||||
import im.status.applet_installer_test.appletinstaller.HexUtils;
|
||||
import im.status.applet_installer_test.appletinstaller.Keys;
|
||||
import im.status.applet_installer_test.appletinstaller.Logger;
|
||||
|
||||
public class InitializeUpdate {
|
||||
public static final int CLA = 0x80;
|
||||
|
@ -36,7 +38,7 @@ public class InitializeUpdate {
|
|||
return challenge;
|
||||
}
|
||||
|
||||
public boolean validateResponse(byte[] encKeyData, APDUResponse resp) throws APDUException {
|
||||
public Keys verifyResponse(Keys cardKeys, APDUResponse resp) throws APDUException {
|
||||
if (resp.getSw() == APDUResponse.SW_SECURITY_CONDITION_NOT_SATISFIED) {
|
||||
throw new APDUException(resp.getSw(), "security confition not satisfied");
|
||||
}
|
||||
|
@ -57,9 +59,17 @@ public class InitializeUpdate {
|
|||
byte[] cardCryptogram = new byte[8];
|
||||
System.arraycopy(data, 20, cardCryptogram, 0, 8);
|
||||
|
||||
return Crypto.verifyCryptogram(encKeyData, this.hostChallenge, cardChallenge, cardCryptogram);
|
||||
byte[] seq = new byte[2];
|
||||
System.arraycopy(data, 12, seq, 0, 2);
|
||||
|
||||
//System.out.printf("key data: %s, %n", HexUtils.byteArrayToHexString(keyData));
|
||||
byte[] sessionEncKey = Crypto.deriveKey(cardKeys.getEncKeyData(), seq, DERIVATION_PURPOSE_ENC);
|
||||
byte[] sessionMacKey = Crypto.deriveKey(cardKeys.getMacKeyData(), seq, DERIVATION_PURPOSE_MAC);
|
||||
|
||||
Keys sessionKeys = new Keys(sessionEncKey, sessionMacKey);
|
||||
|
||||
boolean x = Crypto.verifyCryptogram(sessionKeys.getEncKeyData(), this.hostChallenge, cardChallenge, cardCryptogram);
|
||||
Logger.log("VERIFIED: " + x);
|
||||
|
||||
return sessionKeys;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue