diff options
| author | J08nY | 2018-01-14 12:48:20 +0100 |
|---|---|---|
| committer | J08nY | 2018-01-14 12:48:20 +0100 |
| commit | 6b77638b9c82607b76a0a13a36b3c28418d772ba (patch) | |
| tree | e816e5c4615e3efc5f7c0c3de59f29abd1f4f12b | |
| parent | 83f6e4a30ba708c480ab4db464d41e223db28f26 (diff) | |
| download | ECTester-6b77638b9c82607b76a0a13a36b3c28418d772ba.tar.gz ECTester-6b77638b9c82607b76a0a13a36b3c28418d772ba.tar.zst ECTester-6b77638b9c82607b76a0a13a36b3c28418d772ba.zip | |
| -rw-r--r-- | src/cz/crcs/ectester/reader/CardMngr.java | 153 |
1 files changed, 115 insertions, 38 deletions
diff --git a/src/cz/crcs/ectester/reader/CardMngr.java b/src/cz/crcs/ectester/reader/CardMngr.java index cea46bc..a959f2a 100644 --- a/src/cz/crcs/ectester/reader/CardMngr.java +++ b/src/cz/crcs/ectester/reader/CardMngr.java @@ -4,10 +4,10 @@ import com.licel.jcardsim.io.CAD; import com.licel.jcardsim.io.JavaxSmartCardInterface; import cz.crcs.ectester.common.util.ByteUtil; import javacard.framework.AID; +import javacard.framework.ISO7816; import javax.smartcardio.*; -import java.util.List; -import java.util.Scanner; +import java.util.*; /** * @author Petr Svenda petr@svenda.com @@ -165,50 +165,127 @@ public class CardMngr { } } - public byte[] getCPLCData() throws Exception { - byte[] data; + // Functions for CPLC taken and modified from https://github.com/martinpaljak/GlobalPlatformPro + private static final byte CLA_GP = (byte) 0x80; + private static final byte ISO7816_INS_GET_DATA = (byte) 0xCA; + private static final byte[] FETCH_GP_CPLC_APDU = {CLA_GP, ISO7816_INS_GET_DATA, (byte) 0x9F, (byte) 0x7F, (byte) 0x00}; + private static final byte[] FETCH_ISO_CPLC_APDU = {ISO7816.CLA_ISO7816, ISO7816_INS_GET_DATA, (byte) 0x9F, (byte) 0x7F, (byte) 0x00}; + private static final byte[] FETCH_GP_CARDDATA_APDU = {CLA_GP, ISO7816_INS_GET_DATA, (byte) 0x00, (byte) 0x66, (byte) 0x00}; - // TODO: Modify to obtain CPLC data - byte apdu[] = new byte[HEADER_LENGTH]; - apdu[OFFSET_CLA] = (byte) 0x00; - apdu[OFFSET_INS] = (byte) 0x00; - apdu[OFFSET_P1] = (byte) 0x00; - apdu[OFFSET_P2] = (byte) 0x00; - apdu[OFFSET_LC] = (byte) 0x00; + public byte[] fetchCPLC() throws CardException { + // Try CPLC via GP + ResponseAPDU resp = sendAPDU(FETCH_GP_CPLC_APDU); + // If GP CLA fails, try with ISO + if (resp.getSW() == (ISO7816.SW_CLA_NOT_SUPPORTED & 0xffff)) { + resp = sendAPDU(FETCH_ISO_CPLC_APDU); + } + if (resp.getSW() == (ISO7816.SW_NO_ERROR & 0xffff)) { + return resp.getData(); + } + return null; + } - ResponseAPDU resp = send(apdu); - if (resp.getSW() != 0x9000) { // 0x9000 is "OK" - System.err.println("Fail to obtain card's response data"); - data = null; - } else { - byte temp[] = resp.getBytes(); - data = new byte[temp.length - 2]; - System.arraycopy(temp, 0, data, 0, temp.length - 2); - // Last two bytes are status word (also obtainable by resp.getSW()) - // Take a look at ISO7816_status_words.txt for common codes + public static final class CPLC { + public enum Field { + ICFabricator, + ICType, + OperatingSystemID, + OperatingSystemReleaseDate, + OperatingSystemReleaseLevel, + ICFabricationDate, + ICSerialNumber, + ICBatchIdentifier, + ICModuleFabricator, + ICModulePackagingDate, + ICCManufacturer, + ICEmbeddingDate, + ICPrePersonalizer, + ICPrePersonalizationEquipmentDate, + ICPrePersonalizationEquipmentID, + ICPersonalizer, + ICPersonalizationDate, + ICPersonalizationEquipmentID } - return data; - } + private Map<Field, byte[]> values = new HashMap<>(); - public void probeCardCommands() throws Exception { - // TODO: modify to probe for instruction - for (int i = 0; i <= 0; i++) { - byte apdu[] = new byte[HEADER_LENGTH]; - apdu[OFFSET_CLA] = (byte) 0x00; - apdu[OFFSET_INS] = (byte) 0x00; - apdu[OFFSET_P1] = (byte) 0x00; - apdu[OFFSET_P2] = (byte) 0x00; - apdu[OFFSET_LC] = (byte) 0x00; + public CPLC(byte[] data) { + if (data == null || data.length < 3 || data[2] != 0x2A) { + throw new IllegalArgumentException("CPLC must be 0x2A bytes long"); + } + //offset = TLVUtils.skipTag(data, offset, (short)0x9F7F); + short offset = 3; + values.put(Field.ICFabricator, Arrays.copyOfRange(data, offset, offset + 2)); + offset += 2; + values.put(Field.ICType, Arrays.copyOfRange(data, offset, offset + 2)); + offset += 2; + values.put(Field.OperatingSystemID, Arrays.copyOfRange(data, offset, offset + 2)); + offset += 2; + values.put(Field.OperatingSystemReleaseDate, Arrays.copyOfRange(data, offset, offset + 2)); + offset += 2; + values.put(Field.OperatingSystemReleaseLevel, Arrays.copyOfRange(data, offset, offset + 2)); + offset += 2; + values.put(Field.ICFabricationDate, Arrays.copyOfRange(data, offset, offset + 2)); + offset += 2; + values.put(Field.ICSerialNumber, Arrays.copyOfRange(data, offset, offset + 4)); + offset += 4; + values.put(Field.ICBatchIdentifier, Arrays.copyOfRange(data, offset, offset + 2)); + offset += 2; + values.put(Field.ICModuleFabricator, Arrays.copyOfRange(data, offset, offset + 2)); + offset += 2; + values.put(Field.ICModulePackagingDate, Arrays.copyOfRange(data, offset, offset + 2)); + offset += 2; + values.put(Field.ICCManufacturer, Arrays.copyOfRange(data, offset, offset + 2)); + offset += 2; + values.put(Field.ICEmbeddingDate, Arrays.copyOfRange(data, offset, offset + 2)); + offset += 2; + values.put(Field.ICPrePersonalizer, Arrays.copyOfRange(data, offset, offset + 2)); + offset += 2; + values.put(Field.ICPrePersonalizationEquipmentDate, Arrays.copyOfRange(data, offset, offset + 2)); + offset += 2; + values.put(Field.ICPrePersonalizationEquipmentID, Arrays.copyOfRange(data, offset, offset + 4)); + offset += 4; + values.put(Field.ICPersonalizer, Arrays.copyOfRange(data, offset, offset + 2)); + offset += 2; + values.put(Field.ICPersonalizationDate, Arrays.copyOfRange(data, offset, offset + 2)); + offset += 2; + values.put(Field.ICPersonalizationEquipmentID, Arrays.copyOfRange(data, offset, offset + 4)); + offset += 4; + } - ResponseAPDU resp = send(apdu); + public Map<Field, byte[]> values() { + return values; + } + } - if (verbose) - System.out.println("Response: " + Integer.toHexString(resp.getSW())); + public CPLC getCPLC() throws CardException { + byte[] data = fetchCPLC(); + return new CPLC(data); + } - if (resp.getSW() != 0x6D00) { // Note: 0x6D00 is SW_INS_NOT_SUPPORTED - // something? - } + public String mapCPLCField(CPLC.Field field, byte[] value) { + switch (field) { + case ICFabricator: + String id = ByteUtil.bytesToHex(value, false); + String fabricatorName = "unknown"; + if (id.equals("3060")) { + fabricatorName = "Renesas"; + } + if (id.equals("4090")) { + fabricatorName = "Infineon"; + } + if (id.equals("4180")) { + fabricatorName = "Atmel"; + } + if (id.equals("4250")) { + fabricatorName = "Samsung"; + } + if (id.equals("4790")) { + fabricatorName = "NXP"; + } + return id + " (" + fabricatorName + ")"; + default: + return ByteUtil.bytesToHex(value, false); } } |
