summaryrefslogtreecommitdiff
path: root/smcc/src/main/java/at/gv/egiz/smcc/util/MSCMTransfer.java
diff options
context:
space:
mode:
Diffstat (limited to 'smcc/src/main/java/at/gv/egiz/smcc/util/MSCMTransfer.java')
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/util/MSCMTransfer.java146
1 files changed, 146 insertions, 0 deletions
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/util/MSCMTransfer.java b/smcc/src/main/java/at/gv/egiz/smcc/util/MSCMTransfer.java
new file mode 100644
index 00000000..ea4121a5
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/util/MSCMTransfer.java
@@ -0,0 +1,146 @@
+package at.gv.egiz.smcc.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import javax.smartcardio.CardChannel;
+import javax.smartcardio.CardException;
+import javax.smartcardio.CommandAPDU;
+import javax.smartcardio.ResponseAPDU;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.smcc.GemaltoNetV2_0Card;
+
+import java.nio.ByteBuffer;
+
+public class MSCMTransfer implements MSCMConstants {
+
+ private final Logger log = LoggerFactory
+ .getLogger(MSCMTransfer.class);
+
+ private CardChannel channel;
+
+ public MSCMTransfer(CardChannel channel) {
+ this.channel = channel;
+ }
+
+ public byte[] transfer(byte[] payload, short expectedType) throws IOException, CardException, MSCMException {
+ byte[] header = new byte[] { (byte) 0x80, (byte) 0xC2, (byte) 0x00,
+ (byte) 0x00 };
+ byte[] cmd = null;
+ byte[] len = new byte[1];
+ byte[] con = new byte[] { (byte) 0xD8, (byte) 0xFF, (byte) 0xFF };
+ ByteArrayOutputStream cmdbuffer = new ByteArrayOutputStream();
+ ResponseAPDU response = null;
+ if(payload.length <= 0xFF) {
+ cmdbuffer.write(header);
+ len[0] = (byte) payload.length;
+ cmdbuffer.write(len);
+ cmdbuffer.write(payload);
+ // Transfer cmdbuffer
+ cmd = cmdbuffer.toByteArray();
+ String str = MSCMService.bytArrayToHex(cmd);
+ log.info("Sending: >>> " + str);
+ //ByteBuffer bb = ByteBuffer.wrap(cmd);
+ //ByteBuffer resp = ByteBuffer.allocate(18000);
+ //response = channel.transmit(bb, resp);
+ //int resps = channel.transmit(bb, resp);
+ //ByteArrayOutputStream out = new ByteArrayOutputStream();
+ //out.write(resp.array(), 0, resps);
+ //out.close();
+ //response = new ResponseAPDU(out.toByteArray());
+ response = channel.transmit(new CommandAPDU(cmd));
+ } else { // (> 0xFF)
+ // divide payload
+ int length = payload.length;
+ int offset = 0;
+ int curlen = 0;
+ boolean first = true;
+ while(length > 0) {
+ curlen = (length > 0xF4) ? 0xF4 : length;
+ ByteArrayOutputStream dpay = new ByteArrayOutputStream();
+ dpay.write(con);
+ if(first) {
+ dpay.write(MSCMService.intToBytes(payload.length-18));
+ dpay.write(MSCMService.intToBytes(curlen-18));
+ } else {
+ dpay.write(MSCMService.intToBytes(offset-18));
+ dpay.write(MSCMService.intToBytes(curlen));
+ }
+ first = false;
+
+ dpay.write(payload, offset, curlen);
+ dpay.close();
+ byte[] ppay = dpay.toByteArray();
+
+ cmdbuffer.write(header);
+ len[0] = (byte)ppay.length;
+ cmdbuffer.write(len);
+ cmdbuffer.write(ppay);
+
+ length -= curlen;
+ offset += curlen;
+
+ cmd = cmdbuffer.toByteArray();
+ String str = MSCMService.bytArrayToHex(cmd);
+ log.info("Sending: >>> " + str);
+ response = channel.transmit(new CommandAPDU(cmd));
+
+
+ //ByteBuffer bb = ByteBuffer.wrap(cmd);
+ //ByteBuffer resp = ByteBuffer.allocate(18000);
+ //response = channel.transmit(bb, resp);
+ //int resps = channel.transmit(bb, resp);
+ //ByteArrayOutputStream out = new ByteArrayOutputStream();
+ //out.write(resp.array(), 0, resps);
+ //out.close();
+ //response = new ResponseAPDU(out.toByteArray());
+ log.info("Resp: <<< " + MSCMService.bytArrayToHex(MSCMService.intToBytes(response.getSW())));
+ cmdbuffer.reset();
+ }
+ }
+
+ log.info(" SW : <<< " + MSCMService.bytArrayToHex(
+ MSCMService.intToBytes(response.getSW())));
+ byte[] data = response.getData();
+ log.info("DATA: <<< " + MSCMService.bytArrayToHex(data));
+
+ if(data.length == 0) {
+ return null;
+ }
+
+ MSCMDecoder.checkExceptionInResponse(data, 0);
+
+ if(expectedType == HIVECODE_TYPE_SYSTEM_VOID) {
+ return data;
+ }
+
+ String namespaceString = MSCMDecoder.namespaceHiveToString(data, 0);
+ String typeString = MSCMDecoder.typeHiveToString(data, 4);
+ short resultType = MSCMService.bytesToShort(data, 4);
+ if(expectedType == resultType) {
+ ByteArrayOutputStream str = new ByteArrayOutputStream();
+ str.write(data, 6, data.length-6);
+ return str.toByteArray();
+ } else {
+ throw new CardException("Wrong result type");
+ }/*
+ if(typeString.equals(HIVECODE_TYPE_SYSTEM_STRING_STRING)) {
+ System.out.println(namespaceString + "." + typeString + ": " +
+ MSCMDecoder.decodeString(data, 6));
+ } else if(typeString.equals(HIVECODE_TYPE_SYSTEM_STRING_ARRAY_STRING)) {
+ String[] results = MSCMDecoder.decodeStringArray(data, 6);
+ System.out.println(typeString + ": ");
+ for(String str : results) {
+ System.out.println(str);
+ }
+ } else {
+ System.out.println(namespaceString + "." + typeString + ": " +
+ MSCMService.bytArrayToHex(MSCMDecoder.decodeByteArray(data, 6)));
+ }
+ return data;*/
+ }
+
+}