From e4244c2d1e5b0d816e8e1c7645a68f1f90449508 Mon Sep 17 00:00:00 2001 From: ffaggiani Date: Sun, 28 Aug 2016 16:58:57 -0300 Subject: [PATCH] Logging para que lo pueda levantar el apdu-parser --- src/LogUtils.java | 71 +++++++++++++++++++++++++++++++++++++++++ src/SmartcardTests.java | 62 +++++++++++++++++++++++------------ src/Utils.java | 13 +++++--- 3 files changed, 121 insertions(+), 25 deletions(-) create mode 100644 src/LogUtils.java diff --git a/src/LogUtils.java b/src/LogUtils.java new file mode 100644 index 0000000..290db1e --- /dev/null +++ b/src/LogUtils.java @@ -0,0 +1,71 @@ + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import static java.lang.Compiler.command; + +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +/** + * + * @author ffaggiani + */ +public class LogUtils { + + private static LogUtils instance = null; + private String logFile; + private String logOption = "B"; // B log both Commands and Responses, C log Commands only, R log Responses only + + public static LogUtils getInstance() { + if (instance == null) { + instance = new LogUtils(); + } + return instance; + } + + private LogUtils() { + + } + + public void configure(String path, String option) throws FileNotFoundException, UnsupportedEncodingException { + + switch (option) { + case "C": + this.logOption = "C"; + + break; + case "R": + this.logOption = "R"; + + break; + default: + this.logOption = "B"; + break; + } + + //Create file name with file option in the name + this.logFile = path; + //Clear previous log file + new PrintWriter(this.logFile + "apdu_service_" + this.logOption); + } + + public void logCommand(String command, String type) throws FileNotFoundException, UnsupportedEncodingException { + //Log command according to log option + if (this.logOption.equals("B") || type.equals(this.logOption)) { + //Regex to replace each two character in the string with same two characted plus space + command = command.replaceAll("..(?=.)", "$0 "); + + //Open file in append mode + PrintWriter pw = new PrintWriter(new FileOutputStream(new File(this.logFile + "apdu_service_" + this.logOption),true)); + pw.println(command); + pw.close(); + + } + } + +} diff --git a/src/SmartcardTests.java b/src/SmartcardTests.java index 7d063c6..d74ed68 100644 --- a/src/SmartcardTests.java +++ b/src/SmartcardTests.java @@ -2,9 +2,11 @@ import java.util.Base64; import java.io.BufferedReader; import java.io.ByteArrayInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; @@ -77,15 +79,35 @@ public static void main(String[] args) throws CardException, IOException, List terminals = factory.terminals().list(); // System.out.println("Terminals: " + terminals); // get the first terminal - CardTerminal terminal = terminals.get(0); + CardTerminal terminal = terminals.get(1); // establish a connection with the card Card card = terminal.connect("T=0"); // System.out.println("card ATR: " + // byteArrayToHex(card.getATR().getBytes())); CardChannel channel = card.getBasicChannel(); + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + + //Log Configuration + System.out.println("Input the log path or press enter to default location."); + String logPath = br.readLine(); + + if (logPath.equals("")) { + logPath = System.getProperty("user.dir"); + } + + System.out.println("Input \"C\" for APDU Commands only, \"R\" for APDU Responses only, blank for both \n"); + + String logOption = br.readLine(); + LogUtils logUtils = LogUtils.getInstance(); + logUtils.configure(logPath,logOption); + + System.out.println("Path configured: "+logPath); + + + //Log Configuration done + int swValue = 0; - BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); while (swValue != 9) { @@ -169,22 +191,22 @@ public static void main(String[] args) throws CardException, IOException, selectIAS(channel); FCITemplate fcit7000 = selectFile(channel, "7000"); - if(fcit7000.isIsDF()) - System.out.println(fcit7000.getFileName()); + if (fcit7000.isIsDF()) { + System.out.println(fcit7000.getFileName()); + } FCITemplate fcit7001 = selectFile(channel, "7001"); System.out.println("Binary7001: " + readBinary(channel, fcit7001.getFileSize())); FCITemplate fcit7002 = selectFile(channel, "7002"); - System.out.println("Binary7002: "+ readBinary(channel, fcit7002.getFileSize())); + System.out.println("Binary7002: " + readBinary(channel, fcit7002.getFileSize())); - FCITemplate fcit7004 = selectFile(channel, "7004"); - - System.out.println("Binary7004: "+ readBinary(channel, fcit7004.getFileSize())); + + System.out.println("Binary7004: " + readBinary(channel, fcit7004.getFileSize())); FCITemplate fcit700B = selectFile(channel, "700B"); - System.out.println("Binary700B :"+ readBinary(channel, fcit700B.getFileSize())); + System.out.println("Binary700B :" + readBinary(channel, fcit700B.getFileSize())); break; case 5: @@ -206,7 +228,7 @@ public static void main(String[] args) throws CardException, IOException, break; case 8: System.out.println("Read Card Certificate"); - + selectIAS(channel); readCardCertificate(channel); System.exit(0); break; @@ -243,7 +265,7 @@ public static void main(String[] args) throws CardException, IOException, * * // disconnect card.disconnect(false); } } */ - public static boolean getCPLCData(CardChannel channel) throws CardException { + public static boolean getCPLCData(CardChannel channel) throws CardException, FileNotFoundException, UnsupportedEncodingException { String CLASS = "80"; String INSTRUCTION = "CA"; String PARAM1 = "9F"; @@ -298,7 +320,7 @@ public static boolean getCPLCData(CardChannel channel) throws CardException { } // Retorna true si pudo seleccionar la aplicacion IAS - public static boolean selectIAS(CardChannel channel) throws CardException { + public static boolean selectIAS(CardChannel channel) throws CardException, FileNotFoundException, UnsupportedEncodingException { String CLASS = "00"; String INSTRUCTION = "A4"; String PARAM1 = "04"; @@ -317,7 +339,7 @@ public static boolean selectIAS(CardChannel channel) throws CardException { return (r.getSW1() == (int) 0x90 && r.getSW2() == (int) 0x00); } - private static boolean verifyFP(CardChannel channel, String minutiae) throws CardException { + private static boolean verifyFP(CardChannel channel, String minutiae) throws CardException, FileNotFoundException, UnsupportedEncodingException { String CLASS = "00"; String INSTRUCTION = "21"; String PARAM1 = "00"; @@ -360,7 +382,7 @@ private static boolean verifyFP(CardChannel channel, String minutiae) throws Car // El SW 63Cx indica error de match y que quedan x intentos } - private static boolean verifyPIN(CardChannel channel) throws CardException { + private static boolean verifyPIN(CardChannel channel) throws CardException, FileNotFoundException, UnsupportedEncodingException { String CLASS = "00"; String INSTRUCTION = "20"; String PARAM1 = "00"; @@ -385,7 +407,7 @@ private static boolean verifyPIN(CardChannel channel) throws CardException { // 9000 es SW de exito } - private static boolean isVerifiedPIN(CardChannel channel) throws CardException { + private static boolean isVerifiedPIN(CardChannel channel) throws CardException, FileNotFoundException, UnsupportedEncodingException { String CLASS = "00"; String INSTRUCTION = "20"; String PARAM1 = "00"; @@ -405,7 +427,7 @@ private static boolean isVerifiedPIN(CardChannel channel) throws CardException { // El SW 63Cx indica error de match y que quedan x intentos } - private static boolean unverifyPIN(CardChannel channel) throws CardException { + private static boolean unverifyPIN(CardChannel channel) throws CardException, FileNotFoundException, UnsupportedEncodingException { String CLASS = "00"; String INSTRUCTION = "20"; String PARAM1 = "FF"; @@ -427,7 +449,7 @@ private static boolean unverifyPIN(CardChannel channel) throws CardException { } // Precondicion: Verify PIN - public static boolean MSE_SET_DST(CardChannel channel) throws CardException { + public static boolean MSE_SET_DST(CardChannel channel) throws CardException, FileNotFoundException, UnsupportedEncodingException { String CLASS = "00"; String INSTRUCTION = "22"; @@ -452,7 +474,7 @@ public static boolean MSE_SET_DST(CardChannel channel) throws CardException { } // Precondicion: Verify PIN - public static boolean PSO_HASH(CardChannel channel) throws CardException { + public static boolean PSO_HASH(CardChannel channel) throws CardException, FileNotFoundException, UnsupportedEncodingException { String CLASS = "00"; String INSTRUCTION = "2A"; @@ -480,7 +502,7 @@ public static boolean PSO_HASH(CardChannel channel) throws CardException { } // Precondicion: PSO_HASH - public static boolean PSO_CDS(CardChannel channel) throws CardException { + public static boolean PSO_CDS(CardChannel channel) throws CardException, FileNotFoundException, UnsupportedEncodingException { String CLASS = "00"; String INSTRUCTION = "2A"; @@ -576,7 +598,7 @@ public static FCITemplate selectFile(CardChannel channel, String fileID) throws } - public static String readBinary(CardChannel channel, int fileSize) throws CardException { + public static String readBinary(CardChannel channel, int fileSize) throws CardException, FileNotFoundException, UnsupportedEncodingException { // Construyo el Read Binary, lo que cambia en cada read son P1 y P2 // porque van variando los offset para ir leyendo el binario hasta llegar al tamaƱo total diff --git a/src/Utils.java b/src/Utils.java index e35f07f..234ec27 100644 --- a/src/Utils.java +++ b/src/Utils.java @@ -1,6 +1,8 @@ import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; @@ -78,13 +80,14 @@ public static byte[] hexStringToByteArray(String s) { } public static ResponseAPDU sendCommand(CardChannel chan, byte CLASS, byte INS, - byte P1, byte P2, byte[] data, int le) throws CardException { + byte P1, byte P2, byte[] data, int le) throws CardException, FileNotFoundException, UnsupportedEncodingException { int length = data.length; // largo de la data a mandar int i = 0; int iteraciones = 0; int SW1 = 0, SW2 = 0; byte[] command; ResponseAPDU r = null; + LogUtils logUtils = LogUtils.getInstance(); //si datain vacio // mando el comando con LE solo @@ -99,8 +102,8 @@ public static ResponseAPDU sendCommand(CardChannel chan, byte CLASS, byte INS, r = chan.transmit(new CommandAPDU(command)); SW1 = r.getSW1(); SW2 = r.getSW2(); - System.out.println(byteArrayToHex(command)); - System.out.println(byteArrayToHex(r.getBytes())); + logUtils.logCommand(byteArrayToHex(command),"C"); + logUtils.logCommand(byteArrayToHex(r.getBytes()),"R"); } while (length - i > 0) { iteraciones++; @@ -125,8 +128,8 @@ public static ResponseAPDU sendCommand(CardChannel chan, byte CLASS, byte INS, r = chan.transmit(new CommandAPDU(command)); SW1 = r.getSW1(); SW2 = r.getSW2(); - System.out.println(byteArrayToHex(command)); - System.out.println(byteArrayToHex(r.getBytes())); + logUtils.logCommand(byteArrayToHex(command),"C"); + logUtils.logCommand(byteArrayToHex(r.getBytes()),"R"); i += 0xFF;